SegWitとウィットネス・データ

Segregated Witnessが署名を別のウィットネス・フィールドに移動してトランザクションを再構築する方法 - マリアビリティを修正し手数料を削減します。

0ステップ ·

進捗 0/0

何を学ぶか

  • SegWitトランザクションのウィットネス・フィールドの構造
  • SegWitがトランザクション・マリアビリティを修正する仕組み
  • ウェイト割引と手数料への影響

Segregated Witnessとは?

2017年8月に有効化されたSegregated Witness(SegWit)は、署名データをトランザクション本体から分離します。署名を各インプットのScriptSigフィールドに埋め込む代わりに、SegWitはそれらをアウトプットとlocktimeの間に位置する専用の**ウィットネス(witness)**セクションに移動します。

この一見小さな再構築は、いくつかの重要な問題を解決し、ライトニング・ネットワークのような技術を可能にします。

ウィットネスの構造

SegWitトランザクションでは、各インプットは対応するウィットネス・スタックを持ちます。P2WPKH(Pay-to-Witness-Public-Key-Hash)インプットの場合、ウィットネスは正確に二つのアイテムを含みます:

02                          # Stack item count: 2
47                          # Item 1 length: 71 bytes
3044022047ac...0121          # DER-encoded signature + SIGHASH byte
21                          # Item 2 length: 33 bytes
03b8f12c...a4e9             # Compressed public key (33 bytes)

ウィットネス・スタックはシリアライズされたトランザクション内でインプットと同じ順序で現れます。トランザクションに3つのインプットがあれば、3つのウィットネス・スタックがあります - 一部のインプットがレガシーでも(それらのウィットネス・スタックは空:00)。

完全なSegWitトランザクション

署名されたトランザクションの完全なレイアウト:

02000000                    # Version 2
0001                        # Marker (0x00) + Flag (0x01) → "this is SegWit"
01                          # 1 input
  <32-byte prev tx hash>
  00000000                  # vout 0
  00                        # Empty ScriptSig (SegWit!)
  fdffffff                  # Sequence
02                          # 2 outputs
  e093040000000000          # 300,000 sats
  160014<recipient-hash>    # P2WPKH output
  b882020000000000          # 198,590 sats (change)
  160014<change-hash>       # P2WPKH output
                            # === Witness data starts ===
  02                        # 2 witness items for input 0
    47 <71-byte signature>
    21 <33-byte pubkey>
                            # === Witness data ends ===
00000000                    # Locktime

注意:バージョンの後のマーカー0x00とフラグ0x01は、このトランザクションがウィットネス・データを含むことをパーサーに伝えます。SegWitを理解しないレガシー・ノードはマーカーをゼロ・インプット・トランザクションとして見てスキップします - これがSegWitがソフト・フォークとして後方互換性を達成する方法です。

トランザクション・マリアビリティの修正

SegWit以前は、**トランザクションID(txid)**はScriptSigを含むシリアライズされたトランザクション全体から計算されていました。ECDSA署名は無効化することなく数学的に変更できる(例:S値を否定する)ため、第三者がトランザクションの意味を変えずにtxidを変更することができました。

これは実際の問題でした:

  • ライトニング・ネットワークはtxidで互いを参照するトランザクションの連鎖を構築する必要があります。txidが変わり得るなら連鎖が壊れます。
  • 2014年のMt. Gox事件は、取引所のトランザクション追跡を混乱させるためにマリアビリティを悪用することを含んでいました。

SegWitは非ウィットネス・データのみからtxidを計算することでこれを修正します。署名がウィットネス内にある(本体ではない)ため、それらを変更してもtxidは変わりません。別のwtxid(ウィットネスtxid)がウィットネス・データを含むトランザクション全体をカバーします。

ウェイト割引

SegWitは1 MBブロック・サイズ制限を4,000,000**ウェイト単位(WU)**制限に置き換えます。重要な洞察は、ウィットネス・データが割引を受けることです:

Non-witness data: 1 byte = 4 weight units
Witness data:     1 byte = 1 weight unit

これは100バイトの非ウィットネス・データと100バイトのウィットネス・データを持つトランザクションが:

Weight = (100 × 4) + (100 × 1) = 500 WU
vBytes = 500 ÷ 4 = 125 vB

全200バイトが満ウェイトでカウントされるレガシー・トランザクションと比較:

Weight = 200 × 4 = 800 WU
vBytes = 800 ÷ 4 = 200 vB

実際的な結果:SegWitトランザクションは同等のレガシー・トランザクションより手数料が30~40%安くなります

割引が理にかなう理由

割引は恣意的ではありません。ウィットネス・データは検証中にのみ必要です - トランザクションが検証されると、ノードはそれを破棄できます。非ウィットネス・データ(UTXOを参照するインプット、新しいUTXOを作るアウトプット)は、ノードが永続的に保存しなければならないUTXOセットに永続的な影響を与えます。一時的データの安価な価格設定は、ネットワークに対するより低い長期コストを反映しています。

次のステップ

トランザクションをブロードキャストするに進み、署名されたトランザクションをビットコイン・ネットワークに送信しましょう。