用語集 / 開発者向けリファレンス
Redeem script
別名はredeemScriptです。
- Redeem scriptとは?
- Redeem scriptは、pay-to-script-hashのアウトプットの背後に隠された支出条件の全体を定めるスクリプトであり、署名スクリプトの末尾に支出者が添えて提供し、ハッシュを計算して一致するか確認します。
BIP-16で規定されています。
BIP-16により、送信者は契約全体ではなく20バイトのハッシュに対して支払えるようになり、redeem scriptはそのハッシュが表す契約そのものです。これはスタックの1要素に収まる必要があるため、520バイトが絶対的な上限です。このバイト列を失うと秘密鍵は無価値になるため、redeem scriptはソフトウェアの一部ではなくバックアップの一部となります。
仕組み
コインが動かない間、redeem scriptは見えません。コインを保持するアウトプットにはハッシュとコンセンサスが認識するパターンだけが含まれ、2012年4月1日のブロック173,805からネットワーク全体でそれが強制されています。支払う側も、ブロックエクスプローラーも、条件について何も知ることはできません。
これが明らかになるのは支出時です。署名スクリプトは契約が必要とする引数をプッシュし、最後にシリアライズされた契約そのものを置きます。検証ノードはその最後の要素を取り出してハッシュを計算し、結果をアウトプット内のハッシュと比較し、一致した場合にのみその要素をデシリアライズして残りのスタックに対してコードとして実行します。両方の段階を通過する必要があり、これを運ぶフィールドにはプッシュしか含められないため、スクリプト自体がチェックされる前に挙動を紛れ込ませることはできません。
現存する最も一般的なredeem scriptは、契約ですらありません。2017年以降、SegWitの節約を得ながら旧式のソフトウェアからも支払いを受け取れるようにしたいウォレットは、ウィットネスプログラムをスクリプトハッシュで包みました。そのためredeem scriptは22バイト、すなわちバージョンバイト1つと20バイトの鍵ハッシュであり、実行するものは何もありません。3で始まる数百万もの取引所の出金アドレスは、まさにそれだけを隠しており、それ以上は何も隠していません。
目にする場面
Bitcoin Coreは、スクリプトアドレスを作成するたびにredeem scriptを渡してくれます。また、そのdecodescriptコマンドは16進数表記を読みやすいアセンブリに戻します。ディスクリプタでは、スクリプトはsh(wpkh(...))やsh(multi(...))として明示的に書かれます。これは記録する現代的な方法です。というのも、ディスクリプタウォレットは2021年1月のBitcoin Core 0.21.0で登場し、裸のアドレスをインポートする古い習慣を不要にしたからです。
紛失のパターンは現実的であり、具体的です。シードフレーズは鍵を再生成しますが、任意のスクリプトを再生成することはできず、他の共同署名者の公開鍵を知らせることもできません。そのため、各参加者が自分のシードだけを保管している2-of-3の構成は支出できません。秘密鍵の完全な一式を持ちながら、それらの鍵をどのように組み合わせたスクリプトの記録がないためにコインを失った人々がいます。シードのバックアップごとにディスクリプタを保管し、アドレスに失いたくないものが入る前に、少額で一度ディスクリプタから復元してください。
もう一つ知っておくべきことはサイズの上限です。圧縮公開鍵15個に、それぞれのプッシュプレフィックスと周囲のオペコードを加えると513バイトになり、ちょうど収まります。16個目は収まりません。マルチシグに関する規則ではなく、この上限がスクリプトアドレスの共同署名者を15人に制限しています。
Redeem script vs Witness script
redeem scriptとwitness scriptは、二つの異なる時代において同じ概念上の位置を占め、その違いはバイト列がどこを通るか、そしてどのようにコミットされるかにあります。redeem scriptは160ビットのハッシュでコミットされ、1バイトあたり4重量単位で署名スクリプト内を通ります。witness scriptは256ビットのSHA-256全体でコミットされ、1バイトあたり1重量単位でウィットネス内を通るため、同じポリシーでも支出コストはおよそ4分の1になります。ネストされた構成では両方を同時に使います。redeem scriptは34バイトのウィットネスプログラムであり、witness scriptは実際の契約です。ラップされたSegWitマルチシグのバックアップを記録する場合、片方だけでなく両方を書き留めておく必要があります。