Segregated Witnessウォレット開発ガイド
Overview
このドキュメントのほとんどの内容は、BIP141や BIP143、 BIP144、 BIP145などのsegregated witness関連のBIPに記載されています。このドキュメントは、他の関連ドキュメントへの参照点、また何をすべきで何をすべきではないかのチェックリストと考えてください。
基本的なsegregated witnessのサポート
ウォレットはsegwit互換であると認識されるためには、このセクションの全機能を実装しなければなりません。
P2SHへの送信
- segwit互換のウォレットは、pay-to-script-hashと(BIP16)とそのアドレスフォーマット(BIP13)をサポートしなければなりません。
- 支払いを行う際、ウォレットは与えられたP2SHアドレスを
scriptPubKey
に適切に変換し、トランザクションを作成しなければなりません。 - 支払いを受け取る際、ウォレットはP2WPKHスクリプト(後述)をベースにしたP2SHアドレスを作成し、そのようなアドレスへの支払いを認識できる必要があります。
- 単一署名の支払いのみを受け入れるウォレットの場合でも、これは必須要件です。
P2SH-P2WPKHアドレスの作成
- P2SH-P2WPKHは単一署名の(1から始まる)P2PKHアドレスと互換性があります。
- 他のP2SHアドレスと同様にP2SH-P2WPKHアドレスも3から始まるアドレスです。
- P2SH-P2WPKHのUTXOが使用され、その
redeemScript
が公開されるまで、P2SH-P2WPKHアドレスは(非segwitのマルチシグアドレスなどの)非segwitのP2SHアドレスと区別できません。 - P2SH-P2WPKHアドレスは、P2PKHのように支払いを受け取るために1つの公開鍵のみを使用する場合に使われます。
- P2SH-P2WPKHはP2PKHと同じ公開鍵フォーマットを使用しますが、重要な違いは、P2SH-P2WPKHで使用される公開鍵は必ず圧縮公開鍵である必要があります。33バイトで、
0x02
もしくは0x03
で始まる公開鍵です。非圧縮の公開鍵など他の形式の公開鍵を使用すると、取り返しのつかない資金損失につながる可能性があります。 - P2SH-P2WPKHアドレスを作成するには:
- 公開鍵のSHA256のRIPEMD160(
keyhash
)を計算します。keyhash
の形式はP2PKHと同じですが、圧縮されていない鍵を誤って使用するのを防ぎ、プライバシー強化のためにもkeyhash
の再利用は避けるべきです。 - P2SHの
redeemScript
は常に22バイトです。それはOP_0
から始まり、その後にkeyhash
がプッシュされます。(例:0x0014{20-byte keyhash}
) - 他のP2SHと同様、
scriptPubKey
はOP_HASH160 hash160(redeemScript) OP_EQUAL
となり、そのアドレスは3から始まるP2SHアドレスです。
- 公開鍵のSHA256のRIPEMD160(
トランザクションのシリアライゼーション
- segwit互換のウォレットは
nVersion|txins|txouts|nLockTime
形式のオリジナルのトランザクションフォーマットをサポートしなければなりません。 - segwit互換のウォレットは
nVersion|marker|flag|txins|txouts|witness|nLockTime
形式の新しいシリアライゼーションフォーマットをサポートしなければなりません。nVersion
とtxins
、txouts
、nLockTime
はオリジナルの形式と同じです。marker
は必ず0x00
です。flag
は必ず0x01
です。witness
はトランザクションの全witnessデータをシリアライズしたデータです。- 各txinはwitnessフィールドに関連付けられています。その結果、witnessフィールドの数を示すフィールドは無く、暗黙的に
txins
の数がその数を示します。 - 各witnessフィールドは対応する
txin
のスタックアイテムの数を示すcompactSize
integer で始まります。その後に対応するtxin
のwitnessスタックアイテムが続きます。 - 各witnessスタックアイテムは、そのスタックアイテムのバイト数を示す
compactSize
integerで始まります。 txin
がwitnessデータと関連付けられていない場合は、対応するwitnessフィールドの値は0x00
となり、witnessスタックアイテムの数がゼロであることを示します。
- 各txinはwitnessフィールドに関連付けられています。その結果、witnessフィールドの数を示すフィールドは無く、暗黙的に
- トランザクション内の全ての
txins
がwitnessデータに関連付けられていない場合は、トランザクションはmarker
やflag
、witness
が無いオリジナルのトランザクションフォーマットでシリアライズされなければなりません。例えば、トランザクションのtxins
が全てsegwitのUTXOではない場合、そのトランザクションはオリジナルのトランザクションフォーマットでシリアライズされなければなりません。(コインベーストランザクションを除く) - トランザクションのシリアライゼーションの例はBIP143のexampleに記載されています。ウォレットの開発者は実装が新しいトランザクションフォーマットを正しくパースできているかそのexampleでテストすることができます。
Transaction ID
- segwitでは、トランザクションは2つのIDを持ちます。
txid
の定義は変わらず、オリジナルのシリアライゼーションフォーマットでダブルSHA256した値です。- 新しく
wtxid
が定義され、これはwitnessデータを含む新しいトランザクションフォーマットをダブルSHA256した値になります。 - トランザクションがwitnessデータを持たない場合、
wtxid
とtxid
は同じ値になります。 txid
は引き続きトランザクションのプライマリ識別子として使われます:txin
内で前の出力を参照する際に使用されます。- ウォレットやサービスが現在トランザクションを識別するのに
txid
を使用している場合、アップグレード後も同様に使い続けることができます。
P2SH-P2WPKHの署名の作成と検証
- 非segwitのUTXOを使用する場合は、署名生成のアルゴリズムは今までと変わりません。
- P2SH-P2WPKHのUTXOを使用する場合:
scriptSig
にはredeemScript
しかプッシュしてはいけません。- 対応するwitnessフィールドには署名がプッシュされ、その次に公開鍵がプッシュされなければなりません。
- segwit scriptのための新しい署名生成アルゴリズムがBIP143に定義されています。開発者は注意深くその指示に従い、BIP143のexampleを参考に
sighash
を再現できるか確認する必要があります。 - BIP143の署名生成アルゴリズムは、使用される入力のコインの量をカバーしており、軽量ウォレットやハードウェアウォレットの設計のエアギャップを簡素化します。
- P2SH-P2WPKHの場合、
scriptCode
は先頭のバイトを含めて常に26バイトで、0x1976a914{20-byte keyhash}88ac
となります。redeemScript
でもscriptPubKey
でもないので注意してください。 - Example
ネットワークサービス(オプション)
- ウォレットがピアツーピアネットワークを介してトランザクションを送受信する場合、ネットワークサービスが必要です。
- Segwit互換ノードは、service bit:
NODE_WITNESS = (1 << 3)
を使ってwitnessを提供できることを宣言します。 - witnessデータを持たないトランザクション(=オリジナルフォーマットでシリアライズされたトランザクション)は、
NODE_WITNESS
のサポートの有無に関わらず別のノードに送信できます。 - segwitのUTXOを使用するトランザクション(=新しいシリアライゼーションフォーマットでシリアライズされたトランザクション)は、
NODE_WITNESS
をサポートしているノードにのみ送信できます。 - segiwtのUTXOを使用しているがwitnessデータが取り除かれたトランザクション(=オリジナルのフォーマットでシリアライズされたトランザクション)が、
NODE_WITNESS
をサポートしないノードに送信される可能性があります。ただし、segwitのアクティベート後はそのようなトランザクションは無効となるためブロックにも受け入れられなくなります。 - ネットワークサービスの詳細についてはBIP144に記載されています。
ユーザーのプライバシー
- segwitがアクティベートされて数日は、ネットワーク内に流れるsegwitトランザクション数は限られたものでしょう。
- その間segwitのトランザクションを使用するとBitcoinの追跡が容易になる場合があります。
- デフォルトのお釣りの出力にP2SH-P2WPKHを使用すると、プライバシーに影響を与える可能性があります。
トランザクション手数料の見積もり
- トランザクションサイズに代わって、”virtual size” (
vsize
)と呼ばれる新しいメトリックが定義されました。 - トランザクションの
vsize
は、オリジナルシリアライゼーションでシリアライズしたトランザクションデータを3倍し、新しいシリアライゼーションフォーマットでシリアライズしたトランザクションデータをプラスし、その値を4で割って次の整数に切り上げた数値です。例えば新しいシリアライゼーションフォーマットで200バイトのトランザクションで、marker
とflag
とwitness
を除くと99バイトの場合、vsize
は (99 * 3 + 200) / 4 = 125(切り上げ)となります。 - 非segwitトランザクションの
vsize
は単純にそのトランザクションサイズと同じになります。 - トランザクション手数料は他のトランザクションと
vsize
を比較して見積もられます。(今までのサイズではなく) - 開発者は手数料の見積もりで、4倍の間違いをしないよう気をつける必要があります。
安全なアップグレード
- エンドユーザーはsegwitがネットワーク上で完全にアクティベートされるまで、 P2SH-P2WPKHまたはその他のsegwitアドレスを生成してはいけません。アクティベートの前にP2SH-P2WPKHまたはその他のsegwitアドレスを使用すると、資金を失う可能性があります。
- 同様にお釣り用の出力もアクティベート前にsegwitの出力に送ってはいけません。
- segwitのアクティベーションはBIP9で定義されています。2016年11月15日から2017年11月15日(UTC)までの間、retargetサイクルの2016ブロックのうち1916ブロックがシグナリングされ準備ができた場合、segwitは次のサイクルの後のretargetサイクルでアクティベートされます。
- BIP9のシグナルを判断できないウォレットは、segwitがアクティベートされるまで、segwitのアップグレードバージョンのウォレットをエンドユーザーにリリースすべきではありません。
- 一部のマイナーが新しいルールを正しく実行できない懸念がある場合、アップグレードしたウォレットのリリースは(全てではないにしろ)大半のマイナーが新しいルールに従っていることが確認できるまで延期される可能性があります。ルールに違反している場合、無効な孤立ブロックとして明確に確認できます。
後方互換性
- (1で始まる)P2PKHの支払いの送受信は、引き続きサポートする必要があります。
複雑なスクリプトのサポート
ウォレットが単一署名以外のマルチシグのようなスクリプトタイプをサポートしている場合、以下の要件を満たさなければなりません。
P2SH-P2WSHアドレスの作成
- P2SH-P2WSHアドレスは、P2SHアドレスと互換性があり、任意の複雑なスクリプトを固定サイズのアドレスで表現することができます。
- 他のP2SHやP2SH-P2WPKHアドレスと同様、P2SH-P2WSHアドレスも3から始まります。これらは実際にUTXOを使用し
redeemScript
が公開されるまで区別できません。 - P2SH-P2WSHアドレスを作成するには:
witnessScript
と呼ばれるスクリプトを定義します。witnessScript
のSHA256(scripthash
)を計算します。この時ダブルSHA256やRIPEMD160(SHA256)でなく、単体のSHA256であることに注意してください。- P2SHの
redeemScript
は常に34バイトです。OP_0
から始まり、その後にscripthash
がプッシュされます。(例:0x0020{32-byte scripthash}
) - 他のP2SHと同様、
scriptPubKey
はOP_HASH160 hash160(redeemScript) OP_EQUAL
で、対応するアドレスは3から始まるP2SHアドレスです。
- スクリプトの制限事項
- スクリプトの評価に失敗してはならず、評価後のスタックにはただ1つTRUEとなるスタックアイテムが残っている状態でないといけません。それ以外の場合、評価は失敗します。
- P2SH-P2WSHスクリプト内の公開鍵は圧縮公開鍵でなければならず、それ以外の場合資金が永久に失われる可能性があります。
- OP_IFやOP_NOTIFが使われている場合、その引数は空のvector(false)か
0x01
(true)でなければなりません。他の値を使うと資金が永久に失われる可能性があります。 (BIP draft) - OP_CHECKSIGやOP_CHECKMULTISIGがfailを返す場合、全ての署名は空のvectorでなければなりません。それ以外の場合、資金が永久に失われる可能性があります。 (BIP146)
witnessScript
のデフォルトポリシー制限は3600バイトです。witnessScript
を除いて、witnessスタックアイテムは最大100個で、それぞれ最大で80バイトです。これらの制限を超えるトランザクションは中継されずブロックにも入れられません。- スクリプトサイズの10000バイト制限や、201
nOpCount
などの元々のコンセンサスの制約の多くは、そのままP2SH-P2WSHにも適用されます。 - P2SHの520バイトのスクリプトサイズ制限はP2SH-P2WSHには適用されません。これは3600バイトのポリシー制限と10000バイトのコンセンサス制限に置き換えられます。
P2SH-P2WSHの署名の生成と検証
- P2SH-P2WSHを使用するには:
scriptSig
には、redeemScript
しかプッシュしてはいけません。- 対応するwitnessフィールドの最後のwitnessアイテムは
witnessScript
でなければなりません。 - 新しいBIP143の署名生成アルゴリズムが適用されます:
- OP_CODESEPARATORを使わない場合、
scriptCode
はwitnessScript
のサイズを示すcompactSize
integerとそれに続くwitnessScript
になります。例えば、スクリプトがOP_1 (0x51
)だとすると、シリアライズしたscriptCode
は(0x0151
)になります。 - あまり一般的ではありませんがOP_CODESEPARATORを含むスクリプトについては、BIP143を参照ください。
- OP_CODESEPARATORを使わない場合、
witnessScript
より前のwitnessスタックアイテムはスクリプトを評価する際の入力スタックとして使われます。入力スタックはスクリプトとしては解釈されません。そのため、例えば大きなデータをプッシュするのに0x4c
(OP_PUSHDATA1) を使う必要はありません。- 署名の生成とスタック上のシリアライズされた署名が正しいか検証するには、BIP143のexampleを参考にテストしてください。
- Example
高度な設計
最初のsegwitサポートには以下の機能は必要ありません。
Native Pay-to-Witness-Public-Key-Hash (P2WPKH)
- Native P2WPKHは22バイトの
scriptPubKey
です。このscriptPubKey
はOP_0
で始まり、その後にkeyhash
がプッシュされます。(例:0x0014{20-byte keyhash}
) - P2SH-P2WPKHと同様、
keyhash
は圧縮公開鍵をRIPEMD160(SHA256)した値です。 - Native P2WPKHを使用する際は、
scriptSig
は必ず空で、witnessスタックの形式と署名の生成ルールはP2SH-P2WPKHと同じです(圧縮公開鍵を使用する要件含め)。 - Example
Native Pay-to-Witness-Script-Hash (P2WSH)
- Native P2WSHは34バイトの
scriptPubKey
です。このscriptPubKey
はOP_0
から始まり、その後にscripthash
がプッシュされます。(例:0x0020{32-byte scripthash}
) - P2SH-P2WSHと同様、
scripthash
はwitnessScript
をSHA256した値です。 - Native P2WSHを使用する際は、
scriptSig
は必ず空で、witnessスタックの形式と署名の生成ルールはP2SH-P2WSHと同じです(圧縮公開鍵を使用する要件含め)。 - Example
Native P2WPKHやP2WSHはどうやって使うのか?
- Native P2WPKHおよびP2WSHのアドレス形式はありません。BIP142は延期され全く違う方法で実装される可能性が高いです。別の試みのBIP173 (Bech32)が2017年6月時点で’Draft’ステータスです。
- P2SH版と比べ、Native版のトランザクションの
vsize
はほとんどの場合小さくなります。そのため手数料はより少額になります。 - Native P2WPKHとP2WSHはBIP70のPayment ProtocolのようにRAW
scriptPubKey
プロトコルを使用します。ただ支払人と受取人のプライバシーに影響する可能性があります(下記参照)。 - Native P2WPKHとP2WSHをデフォルトのお釣り用のアドレスとして使用することはできますが、これにより他の人々が容易にお釣りを識別することができます(下記参照)。
- Native P2WPKHやP2WSHの使用は当初は珍しく、プライバシーの問題を引き起こす可能性があります。