ブロックチェーン/レベル IV · プロトコルを深く知る/4.1 Script/レッスン 3
マルチシグネチャ
定足数、バグ、そして存在しなかった鍵
用意するものスクリプトデコード機能を備えたブロックエクスプローラー(例:mempool.spaceやblockchain.com)Bitcoin Coreのソースコード、具体的にはOP_CHECKMULTISIG用のスクリプトインタープリタロジックBIP147およびBIP327の仕様書
問い
- 2つの署名が必要なスクリプトは、なぜスタックから3つの項目を取り出すのでしょうか?
- 空のバイト文字列が、単なる慣習ではなくコンセンサスルールになり得るのはなぜでしょうか?
- 10人分の鍵が1つに統合され、単一の署名者のものと見分けがつかないような署名になると、何が変わるのでしょうか?
探究
- マルチシグネチャスクリプトでは、列挙されたn個の公開鍵に対して、少なくともm個の署名が有効であることが求められます。ロッキングスクリプトにはm、n個の公開鍵、nが記載されており、OP_CHECKMULTISIGはn、n個の鍵、m、続いてm個の署名をポップします。署名は、列挙された順序で鍵と一致しなければなりません。有効な署名がm個未満であれば、その支出は無効です。
- 元の実装にあるコーディングミスにより、OP_CHECKMULTISIGは必要な署名に加えて、スタックから1つ余分に要素をポップします。この「ダミー」要素は暗号学的な検証では無視されますが、存在していなければなりません。存在しない場合はスタックアンダーフローが起こり、トランザクションは失敗します。初期の支出者はこの埋め草としてOP_0を使っていました。ノードはこの位置にどんな値でも受け入れていたため、この慣習は何年も続きました。
- 2017年8月にSegWitとともに有効化されたBIP147(NULLDUMMY)は、この展性(マリアビリティ)の原因をコンセンサスルールに変えました。現在では、ダミー要素は空のバイト配列でなければなりません。空でない値は、たとえ1バイトのゼロであってもスクリプトを失敗させます。これにより、ダミーの内容を差し替えてトランザクションIDを変更することができなくなり、以降のすべての承認においてトランザクションハッシュが安定しました。
- どのマルチシグスクリプトをノードが中継するかは、標準性ルールによって決まります。Bitcoin Coreのデフォルトポリシーでは、ベアマルチシグのアウトプットは鍵3つまでに制限されています。P2SHでラップすれば、マルチシグは最大15個の鍵を使用でき(520バイトのリディームスクリプトによる制限)、P2WSHでは最大20個まで使用できます。この区別により、複雑な企業の資金管理の構成も、基盤となるトランザクション層を肥大化させずに機能します。
- 2つの新しいツールが、従来のマルチシグの方式に取って代わりつつあります。MuSig2(BIP327、2023年)は、TaprootのSchnorr署名の上に構築された独立したプロトコルで、複数の公開鍵を1つの鍵に集約し、標準的なSchnorr署名を生成します。オンチェーンでは、その支出は通常の単一鍵によるTaproot支出と区別がつきません。Taproot自体の一部であるTapscriptはOP_CHECKSIGADDを追加しており、従来のオペコードにあったスタックポップのバグや20鍵の上限なしに、署名を段階的に検証できます。
- これらの仕組みを確認するには、ブロックエクスプローラーを開き、SegWit導入前のベアマルチシグのトランザクションを探してください。scriptSigを見ると、OP_0で始まり、その後に署名が続いています。これを、ウィットネスに空の要素、署名、鍵を列挙したウィットネススクリプトが含まれるP2WSHマルチシグの支出と比較してください。完全な鍵リストをアウトプットに埋め込む場合と入力に埋め込む場合のコストの違いを反映して、バイト数がどう異なるかに注目してください。
重要な事実
- OP_CHECKMULTISIGは、過去のオフバイワンバグによりスタックから1つ余分な要素をポップします。
- BIP147(NULLDUMMY)は、このダミー要素がコンセンサスレベルで空のバイト配列でなければならないと定めています。
- Bitcoin Coreのデフォルトポリシーでは、ベアマルチシグのアウトプットは公開鍵3つまでに制限されています。P2SHでは最大15個、P2WSHでは最大20個まで使用できます。
- MuSig2は複数の鍵を1つの署名に集約し、その支出を通常の単一鍵によるTaproot支出のように見せます。
- TapscriptのOP_CHECKSIGADDはOP_CHECKMULTISIGに代わるもので、余分な要素のバグなしに閾値チェックを可能にします。
- SegWitの有効化(2017年8月)にはBIP147が含まれ、NULLDUMMYルールが中継ポリシーからコンセンサスへと変更されました。
演習 九・六・三・一
9集める説明が見つかるマルチシグ構成(ウォレット、取引所、Lightning、相続プランなど)を9つ挙げ、m-of-nと使用されているスクリプトタイプを記録してください。
6まとめるオンチェーンでの形式に基づき、9つを6つのグループに分けてください:ベアマルチシグ、P2SH、P2SHでラップされたSegWit、P2WSH、Taprootのスクリプトパス、または鍵を集約したTaprootのキーパス。
3絞り込む6つのグループを、各マルチシグ実装方式に内在するプライバシー、バイトコスト、リカバリーの柔軟性に関する3つのトレードオフに絞り込んでください。
1結晶化する空のバイト文字列が、変更可能なポリシーパラメータではなく恒久的なコンセンサスルールになった理由を1文で説明してください。
事実確認
日付、数字、主張は、下記に記載された公表資料と照合して確認しました。