現状のBitcoinのUTXOセットについて、その内訳を調べてみた。
UTXOセットのダンプ
Bitcoin Coreを実行すると、chainstate
ディレクトリ以下のLevelDBのファイルにUTXOセットのデータが格納される。LevelDBは基本的に1つのプロセスしかDBファイルを開けないのと、LevelDBで操作するのも難儀なので、調査しやすいようにまずUTXOセットをファイルにダンプする。これは、Bitcoin Coreのdumptxoutset
RPCを実行することでできる(2〜3分かかる)*1。
$ bitcoin-cli dumptxoutset <生成先のパス> { "coins_written": 146009905, "base_hash": "000000000000000000042303364e5e50144b3d77362842354fb7992af10a80af", "base_height": 821628, "path": "<生成先のパス>", "txoutset_hash": "647a5f9f0e6427b999d633e981674d0af1ed5eddd4b9f8f3a7f1c59eae08146c", "nchaintx": 937337142 }
レスポンスのJSONの各値は、
coins_written
:スナップショットに書かれているコインの量base_hash
:スナップショットのベースとなったブロックのハッシュbase_height
:スナップショットのベースとなったブロックの高さpath
:スナップショットファイルのパスtxoutset_hash
:UTXOセットのコンテンツのハッシュnchaintx
:ベースとなったブロックを含むチェーン内のトランザクション数
出力されたのは、mainnetのブロック821,628時点のUTXOのスナップショットで、約9.1GB。
UTXOセットのデータフォーマット
ダンプしたファイルは以下の形式のデータで構成されている。
まず、先頭に
- 32バイトの
base_hash
- 8バイトの
coins_written
が記録されていて、以降、UTXOの各エントリーが続く。このエントリーのデータ構造は↓
- 36バイトのOutPoint(32バイトのTXIDと4バイトのインデックス)
- UTXOが含まれるブロック高と、コインベースかどうかを示すフラグ
ブロック高を31 bitとして扱い、最下位ビットをコインベースのフラグ(コインベースであれば1、そうでなければ0)として扱った数値をvarintsエンコード - トランザクションアウトプット(TxOut)*2:
UTXOセットの内訳
ダンプファイルをパースしたタイプ別の内訳が↓
タイプ | 個数 |
---|---|
P2PK | 45,537 |
P2PKH | 50,789,846 |
P2SH | 19,190,365 |
P2WPKH | 47,532,135 |
P2WSH | 1,325,019 |
P2TR | 26,183,277 |
Bare Multisig*4 | 934,122 |
Other | 9,604 |
Ordinalsの影響だろうけど、2021年11月にアクティベートされたP2TRが結構多い(UTXOセットなので、インプットのwitnessにデータが格納されるInscriptionの画像系のデータはここには含まれない)。そして、現状のLNチャネルで使われるP2WSHは全体から見ればまだ少数(Simple Taproot Channelとかに移行すると、これもP2TRベースになる)。
ちなみに、UTXOにセットされているsatoshiの量が0のアウトプットのタイプ別の内訳は↓
タイプ | 個数 |
---|---|
P2PK | 2 |
P2PKH | 6,031 |
P2SH | 68 |
P2WPKH | 3 |
Other | 8,846 |
Otherに分類されるUTXOの9割ちょっとが、0 sat UTXOになってるのが分かる。そして、その大半は、
OP_2 OP_3 <38バイトのデータ>
という形式のスクリプトになってる。これもデータの埋め込みに使われてるみたいだけど、OP_RETUNと違ってUTXOセットに残るのが難。ただこのスクリプトは、データがプッシュされているだけなので、マイナーであれば回収可能なUTXO。まぁ、0 satなので回収するメリットはないけど、その分の手数料収入放棄すれば、1ブロックで掃除できるボリュームではある。