Segwit
Segwitとは、BIP141, BIP143, BIP144で提案されたトランザクションの署名をトランザクションの入力部からwitnessと呼ばれる別のデータ領域に移すSegregated Witnessのこと。
【Segwit導入の効果と課題】
・TXIDのmalleability問題の解消
・witness versionを使った新しい拡張方法(OP_〇〇)
・署名データをwitnessに移行することで実質的なブロックサイズを拡大
【トランザクションのmalleability(柔軟性?)問題】
トランザクションへの署名→署名対象データのハッシュ値を生成し、そのハッシュ値に秘密鍵で署名し、その署名データをscript_sigにセットすること。
【問題点】
script_sigには署名ができないためここだけがトランザクションデータの中で唯一改ざんできるポイントになる。トランザクションの他の部分のデータを改ざんすると、トランザクションの署名検証時にエラーとなり、データが改ざんされたことがすぐにわかる。
TXIDはscript_sigを含めたデータから生成されたハッシュ値であるため、script_sigが改ざんされるとTXIDも変わる。
つまり、署名検証に影響を与えないようにscript_sigを変更すればTXIDの異なるトランザクションを作ることができる。
この問題をmalleability問題という。
【script_sigの改ざん方法】
・署名スクリプトの処理に影響のない余計なデータをプッシュ
・プッシュするデータサイズのバイト表現を変更
・ECDSA署名の正負の入れ替え
自分がブロードキャストした時点とブロックに格納した時点とでTXIDが変わっている可能性がある
【malleability問題の解消】
署名はインプットから分離され、witnessと呼ばれるトランザクションの別の領域に格納されることになる。別の領域に格納されるだけで、署名が不要になったりトランザクションのデータサイズ自体が削減されるわけではない。
新たにmarker, flag, witnessが追加され、script_sigはそのまま残っている。
TXIDの計算方法は従来のままだが、script_sigは空であるため署名スクリプトが改ざんされてもTXIDが変わらない。
(WTXIDは、marker, flag, witnessを含む全てのデータをシリアライズ(バイト列?)し、SHA256ダブルハッシュして計算する)
【Segwitのロック/アンロックスクリプト】
【Bech32フォーマット】
今までのビットコインアドレスは、ビット列を文字列にエンコードする際にBase58を使用していたが、SegwitのアドレスではBech32(BIP173)を使用するようになった。
大文字と小文字の区別がなくなった。
Base58のアドレス→version byte + payload + checksum
Bech32のアドレス→human-readable + separator + data
・human-readable→mainnetの場合はbc、testnetの場合はtb
・separator→1固定。名前の通りセパレータの役目。
・data→任意のデータと6文字のチェックサムをセット。1, b, i, o, を除く英数字で構成。
●チェックサム
データ部に含まれる最後の6文字。チェックサムの計算にはBCH符号が使われている。
アドレスの打ち間違えを4文字まで検知し、訂正することができる。
Base58は、検知はできたがどこが誤りであるか、検出できなかった。
BCH符号→任意のアルファベットで構成でき、誤り訂正能力を任意に設定できる誤り訂正符号の一種