用語集 / 開発者向けリファレンス
MSG_WITNESS_TX
- MSG_WITNESS_TXとは?
- ウィットネストランザクション要求は、getdataとして送信され、署名データを除去せずに付けたまま、指定したトランザクションを返すようピアに指示します。
BIP-144で規定されています。
取引をそのtxidでMSG_WITNESS_TXとして要求すると、署名が付いたままの版が返ってきます。Bitcoin Core 0.21.0は2021年1月14日にリリースされ、wtxidリレーを追加し、この要求を主にMSG_WTX(ウィットネスハッシュで要求する方式)に置き換えました。コインを送る側にとっての利点は、改変された署名によって支払いがリレーから消えなくなることです。
仕組み
すべてのsegwitトランザクションには2つの識別子があり、MSG_WITNESS_TXが存在するのは、ピアにどちらの識別子を満たすよう求めているかを伝える必要があるからです。
txidは、ウィットネスを除いたトランザクション(バージョン、入力、出力、ロックタイム)の二重SHA-256です。wtxidは、マーカーバイト、フラグバイト、ウィットネススタックを含む完全なシリアライズ全体に対して取った同じハッシュです。ウィットネスをまったく持たないトランザクションでは、この2つは等しくなります。コインベーストランザクションについては、BIP141がwtxidを32バイトのゼロと定義しています。これは、ウィットネスマークルルートが確実に定まった対象を持つための特別なケースです。
要求コードは0x40000001です。トランザクションタイプ1にウィットネスフラグ0x40000000を加えたものです。タイプ1だけのgetdataを送ると、ピアはウィットネスを除いたバイト列で応答します。これは資金がどこへ行ったかを見るには十分ですが、支払いが承認されていたかを検証するには役立ちません。
この分離が、かつての展性の問題を終わらせました。segwit以前は、第三者が署名を再エンコードしてtxidを変え、送信者をその名前ではもはや存在しないトランザクションの監視に置き去りにすることができました。署名をtxidの外に移すことでその扉は閉じられ、それが事前署名済みのライトニングチャネルトランザクションを安心して頼れるものにしました。
さらにBIP339がこの論理を一歩進めました。verackの前にwtxidrelayメッセージを送るピアは、インベントリタイプ5を使ってwtxidでトランザクションを通知し、Bitcoin Coreは0.21.0からそうしています。利点は拒否キャッシュにあります。不正なウィットネスを1つ拒否したノードでも、同じトランザクションの正しいコピーは拒否しなくなりました。両者のwtxidが異なるからです。MSG_WITNESS_TXは、wtxidリレーを一度もネゴシエートしなかったピアのために残っています。実際には、それはそのリリースより古いソフトウェアを意味します。
どこで目にするか
txidとwtxidを並べて目にする最も分かりやすい場所は、Bitcoin Core自身のトランザクションRPCの出力です。
任意のsegwitの支払いに対してgetrawtransactionを詳細出力付きで呼び出すと、txidフィールドとhashフィールドが得られます。両者は異なります。hashがwtxidであり、その違いは、それ以外はごく普通のJSONオブジェクトにおけるウィットネスデータの唯一の目に見える痕跡です。ブロックエクスプローラーはtxidでインデックスを作成するため、出金が着金したかを確認する際に検索ボックスへ貼り付ける番号はこちらです。
ネットワーク上では、getpeerinfoがメッセージをタイプ別に数えており、その内訳のトランザクション要求は、接続の良いノードでは混在します。現代のピアにはMSG_WTX、取り残されたピアにはMSG_WITNESS_TXです。
これは購入者が設定するものではありません。間接的に関わります。取引所が出金がブロードキャストされたと言い、ウォレットがそれを見つけられないとき、役に立つ問いは、渡されたtxidがそもそもmempoolに届いたかどうかであり、ピアがどのシリアライズを交換したかではありません。
MSG_WITNESS_TX vs MSG_TX
MSG_TXは同じトランザクションを指定し、すべての署名を除いた形で返します。この形はsegwit以前のノードが理解したものであり、NODE_WITNESSを一度も通知しなかったピアにも今なお流れています。区別は見た目上のものではありません。ウィットネスを除いた版を受け取ったノードは、トランザクションの構造を確認できますが、検証はできないため、mempoolに安全に置くことも、検証済みとして先へリレーすることもできません。Bitcoin Coreは、古い形しか話さないピアにsegwitトランザクションを送りません。