Lightning Labsが発表したBitcoin上の新しいアセットプロトコルTaroについて、今回はTaroのアセットツリー周りのデータ構造/表現についてみていく。
Taroのアセットツリー
Taroは、Taprootを利用したアセットのオーバーレイプロトコルになる(TaprootベースのオーバーレイプロトコルはTaroがおそらく初)。なのでTaroを理解する場合、Taprootの知識があった方がいい↓
- 【動画で学ぶブロックチェーン】【Bitcoin】 BIP341 Taproot - 安土 茂亨氏 - GBEC - Blockchain を推進するエンジニアリングコミュニティ -
- 【動画で学ぶブロックチェーン】BIP342 Tapscript - 安土 茂亨氏 - GBEC - Blockchain を推進するエンジニアリングコミュニティ -
Taprootのアウトプットは32バイトの公開鍵だが、この公開鍵は、内部公開鍵(Key-Path)とスクリプトツリー(Script-Path)で構成されている。Taroのアセットは、この内、スクリプトツリー内の構造化されたデータへのコミットメントとして表される。
Taroのアセットツリーは、Merkle-Sum Sparse Merkle Treeというデータ構造のツリーになる↓
techmedia-think.hatenablog.com
Taroのアセットツリーは、以下のような2階層のMS-SMTで構成される。

1階層めは、アセットIDまたはアセットキーファミリーをキーとしたMS-SMT。このツリーのリーフの値は↓
taro_version || asset_id_tree_root || asset_sum
つまり、アセットIDをキーにして、対応するアセットの合計量(asset_sum)と、asset_id_tree_rootをルートとする2階層めのツリーのルートコミットメントおよびtaro_versionから構成されるリーフノードをマッピングしている。
そして2階層めが、アセット毎に作成されるMS-SMT。キーはAsset Script Keyで、リーフは、asset_leafとリーフが保持するそのアセットの量(leaf_sum)で構成される。つまり、あるキーが保持しているアセットの残高を保持するツリーになる。
asset_leaf || leaf_sum
asset_leafは、TLV形式のデータで、以下のデータが現在定義されている。
taro_version:使用するTaroのバージョンasset_id:アセットIDasset_type:アセットのタイプ(0:通常のアセット、1:収集品)amt:このリーフが保持するアセットの量lock_time:アセットを移動可能なタイムロックprev_asset_witnesses:ネストされたTLVで、対象となるアセットリーフへのマージを検証するためのアセットwitnessを含む。split_commitment:通常のアセットについて、新しいアウトプットの分割の検証を許可するために使用。asset_script_version:以下のTLV値の検証を方法を管理する2バイトのアセットスクリプトバージョン。asset_script_key:このアセットリーフを包含するアセットスクリプトにコミット可能なBIP341方式で導出された外部公開鍵。asset_family_key:BIP340で定義された32バイトの公開鍵、で、assert_idに対する64バイトのBIP340署名が続く。- TODO(まだ作業中っぽい)
なお、Asset Script Keyは、BIP341形式の32バイトの公開鍵。なので、2階層めも1階層めと同様に高さ256のツリーになる。
↑のようにアセットの保持状況をネストしたMS-SMTにエンコードして、そのルートハッシュをTaprootのスクリプトツリーにコミットしてるっぽい。
アセットID
↑で既に登場してるけど、オーバーレイプロトコルとしてアセットプロトコルを定義する場合、各アセットを識別するためのIDをどう導出するかを決める必要がある。Taroでは、アセットIDは以下のように計算される32バイトのデータになる。
asset_id = sha256(genesis_outpoint || asset_tag || asset_meta || output_index || asset_type)
ここで、
genesis_outpoint: アセット発行トランザクションで使用されるインプットが参照するUTXOのOutPoint。asset_tag: 特定のアセットを表現するランダムな32バイトの値。複数のアセットを1つのアセットファミリーとしてリンクする際に使用されるタグで、実際にはアセット名のハッシュ値が設定される。asset_meta: 外部リンクやドキュメント、属性値、画像などのメタデータにコミットするために使われるメタデータのハッシュ値(32バイト)。output_index: ジェネシストランザクション内で一意なTaroコミットメントを含むアウトプットのインデックス(4バイト)asset_type: アセットのタイプ(1バイト)
この内、genesis_outpointによってアセットIDの一意性が担保される。
参考
次は、アセットの作成や転送の仕組みについて。