Develop with pleasure!

福岡でCloudとかBlockchainとか。

トランザクション署名時のSIGHASH

Bitcoinトランザクションに署名する際の、署名のスコープの仕様について読んでみる。

SIGHASHの種類

https://bitcoin.org/en/developer-guide#signature-hash-types

OP_CHECKSIGが各署名から非スタック引数を抽出し評価することで、署名者はトランザクションのどの部分に署名するか決めることができるようになる。署名によりトランザクションの一部を変更から保護することで、他のユーザが自分のトランザクションを変更できるようにすることができる。

どのように署名するかはsignature hash typesと呼ばれるオプションで定義されている。現在は以下の3つの基本的なSIGHASHが利用可能。

  • SIGHASH_ALL
    (デフォルト)全ての入力と出力に署名し、署名スクリプトを除く全ての変更から保護する
  • SIGHASH_NONE
    全ての入力には署名するが出力は署名しない。そのため(その出力が他の署名とsignature hash flagsによって保護されていない限り)誰もがsatoshiの送付先を変更できる。
  • SIGHASH_SINGLE
    全入力と入力に対応する出力(入力と同じインデックス番号を持つ出力)にのみ署名する。自分が署名したトランザクションの一部は誰も変更することはできないが、自分が署名していない部分については他の署名者による変更が可能。この入力は他の入力と同様、署名に含まれている。他の入力のシーケンス番号は署名に含まれていないため更新するこができる。

↑の3つの基本型にSIGHASH_ANYONECANPAYを組み合わせることで以下の3つの新しい複合型を作ることができる。

  • SIGHASH_ALL|SIGHASH_ANYONECANPAY
    1つの入力と全出力に署名し、誰もが他の入力の追加や削除ができるようにするもので、追加のsatoshiを付与できるがsatoshiの送付先を変更することはできない。
  • SIGHASH_NONE|SIGHASH_ANYONECANPAY
    1つの入力にのみ署名し、誰もが他の入力や出力の追加・削除できるようにするもので、この入力のコピーを持つ者はいつでもそれを消費できる。
  • SIGHASH_SINGLE|SIGHASH_ANYONECANPAY
    1つの入力とそれに対応する出力にのみ署名し、誰もが他の入力の追加・削除ができるようにする。

各入力は署名されているので、複数の入力を持つトランザクションは複数のsignature hash typesを持つ。
例えば入力が1つのみでSIGHASHがNONEで署名されたトランザクションは、そのトランザクションをブロックに入れるマイナーによって出力を変更される可能性がある。
一方、2つの入力を持つトランザクションの1つの入力がNONEでもう1つの入力がALLで署名されている場合、ALLの署名者がNONEの署名者に相談することなくsatoshiの送り先を決めることができる(その他の者は誰もそのトランザクションは変更できない)。

所感

  • トランザクションの入力への署名というのは、トランザクションのデータから生成したハッシュ値がSIGHASHで、そのSIGHASHへの署名のこと。
  • トランザクションデータからSIGHASHを生成する際に、トランザクションデータのどの部分までを含めるか指定するのがSIGHASH_TYPE。
  • Lightning Networkの仕組みを実装するにあたっても、新しいタイプのSIGHASH(SIGHASH_NORMALIZED、SIGHASH_NOINPUT等)が提案されてるみたい。
  • ただSegwitにより署名抜きにトランザクションのハッシュ(txid)が決まるようになるので、SIGHASH_NOINPUTとかは必要なさそう。