暗号通貨に関する事など

暗号通貨に関する覚書など。メモや日記。

※技術的なことに関して、間違っていたらコメントから指摘していただけると泣いて喜びます

Segwitに関して調べた記録4


前回の続き



Witnessと署名検証に関して

 Segwit(BIP141-BIP145)で新たに導入されるWitnessという構造は、それ以前のBitcoinscriptとは異なる部分が多い。


 例えば、Witnessは今までのBitcoinscriptのように、OpCodeを淡々と処理した結果がtrueであれば署名を正当なものと判断するのではなく、検知した“バージョン”毎に決められた処理を行い、その結果を署名検証の結果とする。


 また、OP_CHECKSIGを行うときなどに使用される署名用のメッセージ(SHA-256doubleHashされる前のデータ)も、今までのように署名前のTxにLockscriptを差し込んだものを使用するのではなく、新しく決められたルールによってシリアライズされたデータを用いる。
(シリアライズは今まで通りHashTypeによってそのルールが異なるが、このブログでは一般的に使われるSIG HASH ALLのみに関して書く)



バージョン0のWitnessProgramとLockscript

 ここではまず、WitnessProgramが何をもって「このLockscriptはWitnessProgramだ」と判断するのか、ということについて書く。


 Segwit後もLockscriptはそれまでと同じようにTx-outのLockscriptフィールドに入れられ、署名検証を行うとき、適宜WItnessProgramか、レガシーなBitcoinscriptかを判断してそれらにあった方法で署名検証が行われる。


 現在はバージョン0のWitnessProgram(P2WPKH,P2WSHの二種類)のみが定められており、下記条件をWitnessProgramのトリガーとしている。


■version0のP2WPKH

  1. Lockscriptが"0"から始まる(この0をバージョンバイトと呼ぶ)
  2. 1byteのバージョンバイト(0x00)に続き、20byteのデータプッシュが続く
  3. 対応するTx-inのunLockscriptが空の状態である


 ここで注意が必要なのは、P2WPKHに使用する公開鍵は圧縮形式の公開鍵でないと受け付けられないという点だ。


■version0のP2WSH

  1. Lockscriptが"0"から始まる
  2. 1byteのバージョンバイト(0x00)に続き、32byteのデータプッシュが続く
  3. 対応するTx-inのunLockscriptが空の状態である



 バージョンバイト(0x00)に続くデータはP2WPKHの場合は圧縮された公開鍵(先頭が0x02または0x03で始まる公開鍵)をHash160(SHA-256_RIPEMD-160)したものであり、P2WSHの場合はredeem-scriptをHash256(SHA-256doubleHash)したデータである。


 上記の他に、既存のP2SHでネストさせる方法とそのトリガーもあるが、ここでは紹介しない。簡単に言うと、LockscriptがP2SHで、redeem-scriptにP2WPKHやP2WSHを閉じ込めることも可能であるということだ。


 Segwitに対応したノード、クライアントは上記フォーマットのLockscriptを検知すると、Witness用の署名・検証に処理を移す。



署名検証

 では実際、P2WPKHやP2WSHをノードやクライアントが検知した場合、どういった署名検証の処理を行うのか。

 バージョン0で定められているP2WPKHとP2WSHの処理の内容は実際のところ、それまでのP2PKHやP2SHと変わらない。例えばP2WPKHの場合、Witnessに [signature] [publickey] の順にデータが格納され、検証の際にはpublickeyHashをP2WPKHに格納されたそれと照らし合わせ、一致すれば [signature] [publickey] をECDSA検証器にかける。

(流れはP2PKHの OP_DUP ... OP_CHECKSIG と同じ流れ)



未知のバージョンを検知した時

 現在バージョン0のみが定められているという話をしたが、例えば未知のバージョンが検知された時、WitnessProgramはどういった動きをするか。


 結論から言うと、未知のバージョンを検知した時WitnessProgramはそのLockscriptをANYONE_CAN_PAY(誰でも使用することが出来るTx-out)として処理を行う。つまり、誰が使用したとしても署名検証を通す。


 なぜこんなことをするのか、それは将来新しいバージョンのWitnessProgramをフォークして追加した時に、後方互換を意識しなくて済むようにするためだ。新しいプログラムを追加した際、古いノードがネットワークに紛れていても、そのノードはそのTx-outをANYONE_CAN_PAYとして取り扱うので、特別な後方互換手段を用意する必要がなくなる。




次に署名用メッセージのシリアライズの話に移りたいが、長くなってしまうのでここで一旦区切る。
〜5に続く〜

×

非ログインユーザーとして返信する