ビットコイン・インスティテュート

BIP 16 — スクリプトハッシュへの​支払い

  BIP: 16
  Layer: Consensus (soft fork)
  Title: Pay to Script Hash
  Authors: Gavin Andresen <gavinandresen@gmail.com>
  Status: Deployed
  Type: Specification
  Assigned: 2012-01-03

概要

本 BIP は、ビットコインのスクリプトシステムに向けた新しい「標準」トランザクション型を記述し、この新しいトランザクションにのみ適用される追加の検証ルールを定める。

動機

pay-to-script-hash の目的は、トランザクションを償還するための条件を提示する責任を、資金の送金者から償還者へと移すことである。

この利点は、送金者が、QR コードで走査するのに十分短く、容易にコピー&ペーストできる固定長 20 バイトのハッシュを用いて、どれほど複雑であっても任意のトランザクションに資金を投入できるようになることである。

仕様

リレーされ、マイニングされたブロックに含められる新しい標準トランザクション型が定義される。

OP_HASH160 [20-byte-hash-value] OP_EQUAL

[20-byte-hash-value] は、20 バイトをスタックへプッシュするオペコード (0x14) に、ちょうど 20 バイトを続けたものでなければならない。

この新しいトランザクション型は、標準的な scriptSig によって償還される。

...signatures... {serialized script}

これらの pay-to-script アウトポイントを償還するトランザクションは、serialized scriptredeemScript とも呼ばれる)自体が、他の標準トランザクション型のいずれかである場合に限り、標準とみなされる。

トランザクションのリレー時、または新しいブロックへの取り込みを検討する際に、これらのアウトポイントを検証するルールは以下のとおりである。

  1. scriptSig 中に「push data」以外の操作が含まれる場合、検証は失敗する。
  2. 通常の検証が行われる。すなわち、署名と {serialized script} から初期スタックが作成され、スクリプトのハッシュが計算され、それがアウトポイント中のハッシュと一致しなければ直ちに検証は失敗する。
  3. {serialized script} が初期スタックからポップされ、ポップされたスタックとデシリアライズされたスクリプトを scriptPubKey として、トランザクションが再度検証される。

これらの新しいルールは、タイムスタンプが 1333238400(2012 年 4 月 1 日)以上であるブロック中のトランザクションを検証する際にのみ適用されるべきである [1]。ブロックチェーン中には 1333238400 より前の、これらの新しい検証ルールを満たさないトランザクションが存在する [2]。それより古いトランザクションは旧ルールの下で検証されなければならない(詳細は後方互換性の節を参照)。

例えば、1 署名を要求するトランザクションに対応する scriptPubKey と scriptSig は次のとおりである。

scriptSig: [signature] {[pubkey] OP_CHECKSIG}
scriptPubKey: OP_HASH160 [20-byte-hash of {[pubkey] OP_CHECKSIG} ] OP_EQUAL

{serialized script} 内の署名オペレーションは、ブロックごとに許容される署名オペレーションの最大数(20,000)に対して以下のとおり寄与する。

  1. OP_CHECKSIG および OP_CHECKSIGVERIFY は、評価されるか否かにかかわらず、1 件の署名オペレーションとしてカウントされる。
  2. OP_1 から OP_16 の直後に置かれた OP_CHECKMULTISIG および OP_CHECKMULTISIGVERIFY は、評価されるか否かにかかわらず、1 件から 16 件の署名オペレーションとしてカウントされる。
  3. それ以外のすべての OP_CHECKMULTISIG および OP_CHECKMULTISIGVERIFY は、20 件の署名オペレーションとしてカウントされる。

例:

+3 件の署名オペレーション:

{2 [pubkey1] [pubkey2] [pubkey3] 3 OP_CHECKMULTISIG}

+22 件の署名オペレーション:

{OP_CHECKSIG OP_IF OP_CHECKSIGVERIFY OP_ELSE OP_CHECKMULTISIGVERIFY OP_ENDIF}

論拠

本 BIP は BIP 12 を置き換える。BIP 12 は、本 BIP のすべて、およびそれ以上のことを実現するための新しい Script オペコード(“OP_EVAL”)を提案していた。

本 BIP(および pay-to-script-hash アドレス形式を扱う BIP 13)の動機はいくぶん議論を呼ぶものである。何人かは、これは不要であり、複雑な/マルチシグネチャのトランザクション型は、送金者に完全な {serialized script} を単純に渡すことでサポートすべきだと考えている。著者は、本 BIP が、base58 エンコードされた 20 バイトのビットコインアドレス宛の送金のために既に構築されている支援インフラストラクチャすべてへの変更を最小限に抑えられると考えており、これにより加盟店や取引所その他のソフトウェアが、より早期にマルチシグネチャトランザクションのサポートを開始できるようになる。

一つの「特別な」scriptPubKey の形式を認識し、それが検出された際に追加の検証を行うというのは醜いやり方である。しかし、代替案はいずれもさらに醜いか、実装がより複雑になるか、および/または表現言語の力を危険な形で拡張してしまう、というのがコンセンサスである。

署名オペレーションのカウントルールは、{serialized script} を静的に走査することで、容易かつ迅速に実装できるよう意図されている。ビットコインは、マイナーに対するサービス拒否攻撃を防ぐため、ブロックごとの署名オペレーション数の最大値を課している。もし上限がなければ、悪意あるマイナーは検証に数十万件の ECDSA 署名オペレーションを要するブロックをブロードキャストし、ネットワークの残りが現在のブロックの検証に取り組んでいる間に、次のブロックの計算で先行できてしまうかもしれない。

旧実装に対しては 1 承認攻撃が存在するが、実際には高コストかつ困難である。攻撃は次のとおりである。

  1. 攻撃者は、旧ソフトウェアからは有効に見えるが新実装では無効な pay-to-script-hash トランザクションを作成し、それを用いて自分自身にコインを送る。
  2. 攻撃者はさらに、その pay-to-script-hash トランザクションを使う標準トランザクションを作成し、旧ソフトウェアを実行している被害者に支払う。
  3. 攻撃者は、両方のトランザクションを含むブロックをマイニングする。

被害者が 1 承認の支払いを受け入れた場合、ネットワークの残りが攻撃者の無効なブロックを上書きした時点で両方のトランザクションが無効化されるため、攻撃者が勝利する。

この攻撃は、攻撃者がネットワークの残りによって無効化されると分かっているブロックを作成する必要があるため、コストが高い。また、ブロックの作成自体が困難であり、利用者はより高額のトランザクションについて 1 承認のトランザクションを受け入れるべきでないため、実行は難しい。

後方互換性

これらのトランザクションは旧実装にとって非標準であり、(典型的には)リレーもブロックへの取り込みも行われない。

旧実装は、本 BIP を完全にサポートするソフトウェアによって作成されたブロックを検証する際、{serialize script} のハッシュ値が一致することのみを検証し、それ以外の検証は行わない。

悪意ある pay-to-script トランザクションによるブロックチェーンの分裂を避けるには、以下の 1 件のケースの慎重な処理が必要である。

  • 新しいクライアント/マイナーにとっては無効だが、旧クライアント/マイナーにとっては有効な pay-to-script-hash トランザクション。

長期にわたるブロックチェーンの分裂を発生させることなく円滑にアップグレードするには、マイナーの 50% を超える割合が新しいトランザクション型の完全な検証をサポートし、かつ同時に旧検証ルールから新ルールへ切り替える必要がある。

ハッシュパワーの 50% を超える割合が本 BIP をサポートしているかを判断するため、マイナーは自身のソフトウェアをアップグレードし、作成するブロックのコインベーストランザクションの入力に文字列 “/P2SH/” を含めるよう求められる。

2012 年 2 月 1 日、直近 7 日間について pay-to-script-hash をサポートするブロック数を判定するため、ブロックチェーンが調査される。コインベースに “/P2SH/” を含むブロックが 550 件以上あれば、2012 年 2 月 15 日 00:00:00 GMT 以降のタイムスタンプを持つすべてのブロックについて、pay-to-script-hash トランザクションが完全に検証されるものとする。1 週間でおよそ 1,000 件のブロックが作成されるため、550 件はネットワークのおよそ 55% が新機能をサポートしていることに相当するはずである。

ハッシュパワーの過半数が新しい検証ルールをサポートしない場合、展開は延期される(多数派が決して得られないことが明らかになった場合は却下される)。

シリアライズされたスクリプトサイズの 520 バイト制限

後方互換性の要件の帰結として、シリアライズされたスクリプト自体が、他の PUSHDATA オペレーションと同じルール(520 バイトを超えるデータをスタックにプッシュしてはならないというルールを含む)に従う。したがって、参照される償還スクリプトが 520 バイトを超える場合、その P2SH アウトプットを使用することはできない。例えば OP_CHECKMULTISIG オペコード自体は最大 20 個の公開鍵を受け付けられるが、33 バイトの圧縮公開鍵を用いる場合、償還に最大 15 個の公開鍵しか要求しない P2SH アウトプットしか使用できない: 3 バイト + 15 個の公開鍵 × 34 バイト/公開鍵 = 513 バイトである。

リファレンス実装

https://gist.github.com/gavinandresen/3966071

関連項目

  • https://bitcointalk.org/index.php?topic=46538
  • Pay to Script Hash 用のアドレス形式を扱う BIP
  • M-of-N マルチシグネチャトランザクション BIP 11
  • 品質保証テストチェックリスト

参考文献

  1. -bip16 と -paytoscripthashtime のコマンドライン引数を削除 (https://github.com/bitcoin/bitcoin/commit/8f188ece3c82c4cf5d52a3363e7643c23169c0ff)
  2. トランザクション 6a26d2ecb67f27d1fa5524763b49029d7106e91e3cc05743073461a719776192 (https://web.archive.org/web/20141122040355/http://blockexplorer.com/tx/6a26d2ecb67f27d1fa5524763b49029d7106e91e3cc05743073461a719776192)