今回は、BitcoinのScriptの新しい命令であるOP_EVALについてのBIPです。
https://github.com/bitcoin/bips/blob/master/bip-0012.mediawiki
概要
このBIPは、Bitcoinのscriptの新しいオペコード(OP_EVAL)と、受け取り側がトランザクションを変更できる新しいトランザクションの形式を説明します。
動機
安全なウォレットと安全なトランザクションだけで、古いマイナーとクライアントへの後方互換を保ったまま、複雑なトランザクションを実装することができる。
仕様
OP_EVALは、既にあるOP_NOP1の機能を以下のように再定義するものです。
- トランザクションの検証作業中に、スタックの一番上の値をpopし、それをScriptの形式に復号し、Scriptとして実行します。
- もしスタックの一番上のアイテムがなかったり、それがScriptの命令じゃなかった場合はトランザクションは無効となります。
- Scriptの命令に復号したときにOP_CODESEPARATORが含まれていれば、トランザクションは向こうになります。
- Scriptの命令に復号したときにOP_EVALが含まれていれば、それも実行されますが、OP_EVALは2つまでしか深く呼び出しできません。
- OP_EVALの中を実行し、トランザクションが無効化される結果になった場合、OP_EVALの呼び出し元でもトランザクションが無効化されます。
新しいScriptPubKeyの形式は以下のようになります。
DUP HASH160 {20-byte-hash-value} EQUALVERIFY OP_EVAL
ScriptSigは以下のようになります。
...signatures... {任意の値=変換されたScriptの命令}
OP_EVALを使用するScriptPubKeyはスタンダードトランザクションとして標準のものになります。
実装
OP_EVALは、ビットコインの受け取り側がビットコインをどのように使うかを、ビットコインの送り主側が知ることができます。
送り主は、新しいアドレス形式などを含む複雑なトランザクションに対応するために、変換されたScriptを知っているだけで良くなります。
もし復号化されたScriptが複雑だったり、マルチシグネチャを利用していた場合、結果的に多いトランザクションフィーを払うのが、送り主ではなく受け取り側になります。
もし、OP_EVALがScriptに複雑さを追加することになり、そしてそれが問題になるようなことがあるかもしれません。また、セキュリティ的にそれが良くないこともあります。
同じことが既にあるBitcoinのScriptにも言えます。ScriptPubKeyは、ネットワークを超えてBitcoinの仕組み・実装を細かく変更できます。OP_EVALはただデータの場所を移動するだけです。おバカな人がわざわざBitcoin-coreのコードを書き換えなくても、セキュリティを保ったまま機能の追加ができます。
OP_EVALに対応しない古いクライアントに対して、ただのNOPとして1認証攻撃という攻撃をすることができます。しかし、これは難しいです。以下に方法を述べます。
- 攻撃者は、古いクライアントでは有効に見えて、新しいクライアントでは無効なOP_EVALを含むトランザクションを作ります。
- また、攻撃者は、1のトランザクションを入力とする、ティム宛の送金トランザクションを作ります。
- 攻撃者は、1と2のトランザクションを含むブロックを採掘します。もしティムが1認証でこれを受け入れれば、ネットワークがブロックを無効と認定するまでの間、攻撃に成功します。
攻撃者は、不正なブロックを自力で掘らなければならないので、攻撃の難易度は高いです。また、高い価格の送金を1認証を完了させるような状況はBitcoinを使うビジネスとしては普通はないのも理由になります。
後方互換
驚くことに。、OP_EVALはOP_NOP1を書き換えるものですが、古いクライアントでも有効とみなされます。古いクライアントは、変換されたScriptの命令が値としておかしくないかを確認するだけです。もしOP_EVALがただのNOPとして有効であれば、トランザクションが有効としてみなされます。
古いクライアントはOP_EVALを無視します。また、一般的ではないトランザクションをブロックに取り込んでくれるマイナーか、新しいクライアントを使うマイナーも必要になります。
OP_EVALがブロックチェーンを分岐させないために、以下の2つのケースを気をつける必要があります。
- OP_EVALを使い、新しいクライアントでは無効だが古いクライアントでは有効なトランザクション
- OP_EVALを使い、新しいクライアントでは有効だが古いクライアントでは無効なトランザクション
ケース1の場合、新しいクライアントとマイナーは2012年2月1日まで古いOP_EVALをただのNOPとして認識するようにします。それまでは、OP_EVALが承認されるかどうか確認するため、マイナーがブロックに"OP_EVAL"という識別子がついているかどうか確認します。2012年1月15日の時点で、OP_EVALに対応するマイナーが50%以下の場合、そのトランザクションはOP_EVALに対応するマイナーが50%を超えてから有効になります。プロトコルの移行はそれまで拒否されます。
ケース2の場合、新しいクライアントはそもそもOP_EVALがただのNOPだった場合とOP_EVALである場合の両方でトランザクションが有効であることを確認します。例を以下に示します。
scriptSig: {OP_11を変換した値}
scriptPubKey: OP_EVAL OP_11 OP_EQUAL
実際の実装
以下も参照してください。
"Bitcoin Address 01" BIP
M-of-N Multisignature Transactions BIP 11