ウォレットのTaprootアドレス生成対応に必要な”Output Script Descriptor"とは
2週間前の記事でTaprootアドレスの使用が全体の0.5%程度と伸び悩んでいることを紹介しました。1つの大きな障壁はウォレットの対応で、P2TRアドレスを生成できるウォレットが未だ少ない理由の1つにOutput Script Descriptorというものを持つことが必要(強く推奨)なことが挙げられます。
4月にリリースされたBitcoin Core 23.0において、新しいウォレットを作るとP2TRアドレス(bech32m)生成用のDescriptorが実装されました。まだ新規アドレス生成方式の既定はP2WSHアドレス(bech32)のままですが、P2TRを既定に設定することもできます。
今日は比較的新しいウォレット内の概念であるOutput Script Descriptorとは何なのかについて解説します。
HDウォレットの仕組みと欠点
従来から皆さんが使っているウォレットはBIP32に定義されたHDウォレットの可能性が高いです。そう、あの12/24単語のシードフレーズから、バージョンなどいくつかの情報を元に秘密鍵が大量に生成できるものです。
シードから多数の公開鍵(アドレスの元)が一定のルールに則って階層的に導出されるHDウォレットは通常のシングルシグのアドレスの生成や他のウォレットソフトへの乗り換えには便利ですが、大きな欠点がいくつかあります。
まず、アドレスの生成メカニズムを指定しないため、各公開鍵ごとに数パターンあるすべてのアドレスをチェックする必要があります。例えば同じ公開鍵でも、P2PK、P2PKH、P2SH-P2WPKH、P2WPKHと、アドレスの種類によって異なるアドレスが生まれます(当たり前ですね)。したがって、例えばシードフレーズからリカバリーした後にウォレットはこれをすべて想定してスキャンする必要があり、効率が良くありません。
次に、アドレスを大量に導出し、まばらに資金が存在するとき、ウォレットがどのアドレスに資金があるかを知る方法がありません。例えばある導出パスの1番目と100番目と1000番目のアドレスにのみ資金が存在する場合、ウォレットは何番目のアドレスまでスキャンしてくれるかによって検知する残高が異なってしまいます。「もっと読み込む」のような機能があっても、もしユーザーが1000番目のアドレスのことを忘れていたら、知らずのうちにセルフGOXしてしまうかもしれません。
最後に、シングルシグという表現でお気づきかもしれませんが、マルチシグのデータの問題もあります。マルチシグアドレスから送金するには使用する秘密鍵の他にマルチシグに参加している公開鍵の一覧とマルチシグスクリプト本文が必要になります。しかし、これらのデータは当然自分のシードフレーズから導出できるものではないため、他のウォレットへと引き継いだりリカバリーすることが比較的難しく、GOXリスクを高める要因でした。
もちろん、アドレスを生成するときに使用したウォレットであれば、ウォレット内でこれらの情報を管理することはできます。問題はリカバリーしたり、ウォレットを乗り換えた際にこれらの情報を新しいウォレットに取り込む形式が定められていないことでした。ほかにもDescriptorはチェックサムがあるなど、ポータビリティを意識したものとなっています。
ちなみに、PSBTの登場で後者のマルチシグ関連情報問題に関してはDescriptorを使わずとも共有・バックアップしやすい標準形式が誕生したといえます。
DESCRIPTORのミソ
Descriptorはとあるアドレス(Output)に関連して導出に使用するスクリプトを表現するための言語です。例を見ていくと理解しやすいでしょう。
例えば以下のDescriptorはそれぞれP2PKH、P2SH-P2WPKH、そしてマルチシグのOutputを示しています。
pkh(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)
sh(wpkh(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))
multi(1,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)
前者2つはこの公開鍵に関してアドレスの導出方法が1つに定まるので、4種類すべてを生成し検知する必要がなくなるメリットがあります。後者に関しても、公開鍵の順番や署名の必要数など、スクリプトの導出に必要な情報がまとまっているのでこのDescriptorに対応するマルチシグアドレスを確実に検知できます。
ちなみに先程出てきたPSBTとDescriptorも相性が良く、River Financialというビットコイン専門の金融サービスを提供している会社はこの2つのテクノロジーを中心にサービスを組み立てているようです。
Field Report: Using Descriptors and PSBT at River Financial https://bitcoinops.org/en/river-descriptors-psbt/
従来のHDウォレットにDescriptorを追加することも考えられます。下記の例ではマスター公開鍵xpubから1/2というパスで導出されるP2PK, P2PKH, P2SH-P2WPKH, P2WPKHの4種類のアドレスすべてを表現しています。
combo(xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw/1/2)
TAPROOTとの関連性
さて、ここまで来たら勘の良い読者はなぜP2TRアドレスの生成にDescriptor Walletが強く推奨されるかに気づいているかもしれません。これはP2TRのUTXOは公開鍵への署名による使用方法以外にTaptreeに含めたスクリプトによる使用もあり得るからです。
例えば通常は自分の秘密鍵で署名できるが、死後に妻子や弁護士などがマルチシグで送金できるような条件を記したTapleafのあるP2TRアドレスを生成したとします。この場合は従来のマルチシグなどに使われるP2SHアドレスと同じく、スクリプトの内容と公開鍵一覧などを保管する必要があり、これをウォレット間で移動したりリカバリーするのにDescriptorという共通形式があることが望ましいということです。
せっかくなので上記の例をTaprootのDescriptorにしてみましょう。
tr(c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,{multi_a(2,03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe),multi_a(2,03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe,02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)})
この場合はc6~の公開鍵に対応する自身の秘密鍵か、03f~と022~の妻と子の2-of-2、もしくはそこに弁護士02c~を加えた2-of-3で動かせるようになります。条件が増えるとDescriptorもかなり長くなることがわかります。(multiではなくmulti_aなのはTapscriptではOP_CHECKMULTISIGは使用できずシュノア署名をOP_CHECKSIGADD等で加算してから検証するためです)
Taprootで複雑なスクリプトを表現する場合は、一旦Miniscriptで記述してそれをDescriptorにコンパイルする流れを想定しているようです。Miniscriptについては本稿で過去に取り上げています。
【2019/8/22】Miniscriptがビットコインのスマートコントラクトを使いやすくする
https://www.facebook.com/.../bitc.../posts/2369292786500382/
まとめ
・Output Script Descriptors / Wallet Descriptorsはスクリプトや公開鍵に対応するアドレスの導出方法を表現するメタデータ
・これが存在するおかげでスクリプトを利用したアドレス形式(P2SH, P2WSH, P2TR)は特にウォレット間の乗り換えやリカバリーが自在に行えるようになり、セルフGOXのリスクが削減される
・複雑なスクリプトのDescriptorは人間には扱いにくいので、もし作成する場合は高級言語のMiniscriptからコンパイルしてDescriptorを残すという流れが主流になりそう
・P2TRアドレスやTapscriptを活用したウォレットが出てくるにはDescriptorのtr()関数が実装されるのを待つ必要がある。Bitcoin Coreさえも4月にリリースされた23.0でようやく対応

次の記事
読者になる
一緒に新しい世界を探求していきましょう。
ディスカッション