用語集 / 開発者向けリファレンス
署名スクリプト
別名はSignature script、scriptSigです。
- 署名スクリプトとは?
- 署名スクリプトとは、インプットが使用するアウトプットのpubkey scriptを満たすために、そのインプットが保持する解錠用データのことであり、現代のSegWitインプットでは空です。
トランザクションの各インプットは、過去のアウトプットを指し、それを支出する権利があることを証明しなければなりません。Bitcoin CoreはこのフィールドをscriptSigと名付けています。レガシーのpay-to-public-key-hashのインプットでは、71バイトまたは72バイトの署名と33バイトの公開鍵、およそ107バイトが格納されます。SegWit以降、その証明は通常別の場所に置かれるようになり、bech32への出金のコストが低い主な理由もそこにあります。
仕組み
署名スクリプトは先に実行され、その結果をスタックに残して、アウトプットのスクリプトがそれを消費します。両者は結合された1つのプログラムとして実行されるのではなく、順番に実行され、その間でスタックが引き渡されます。この分離は、当初の設計が悪用可能であることが判明した後、2010年に導入されました。
リレーポリシーは、このフィールドにデータのプッシュ以外を含めないことを義務付けています。条件分岐も、演算も、処理を行うオペコードも許されません。この制限があるのは、支出者がこれらのバイトを完全に制御できるためであり、入力時に攻撃者にロジックを実行させることは、ネットワークがずっと前に塞いだ問題を再び開くことになるからです。pay-to-script-hashはこのルールを任意の設定ではなくコンセンサスの要件にします。redeemスクリプトが最後の単純なプッシュとして届かなければならないからです。
そのサイズは、何をアンロックするかによって完全に決まります。レガシーの単一鍵のインプットは、署名と鍵を運びます。ネストされたSegWitのインプットは正確に23バイト、すなわち22バイトのウィットネスプログラムの単一のプッシュを運び、それ以外のすべてをウィットネスに移します。ネイティブのbech32またはbech32mのインプットは何も運びません。シリアライズされたフィールドは長さゼロを表す1バイトです。
署名スクリプトが何の証明でもないインプットが1つあります。coinbaseトランザクションの唯一のインプットにはアンロックすべき過去のアウトプットがないため、このフィールドは2バイトから100バイトの自由な領域として転用され、BIP-34以降はブロック高で始まらなければなりません。マイナーは2009年からそこにメッセージ、投票、ジョークを署名して書き込んできました。
表示される場所
任意のトランザクションをデコードすると、各インプットにassembly表示とhex表示を備えたscriptSigオブジェクトが表示されます。ネイティブSegWitまたはTaprootのインプットではどちらも空の文字列になり、代わりに別のウィットネスフィールドがデータを保持します。この見た目の非対称性は、古いトランザクションがどのアドレス形式を使ったかをひと目で見分ける最短の方法です。
また、広く誤解されている歴史の一場面も説明します。scriptSigがトランザクションIDの計算に含まれていたため、第三者が署名を無効にせずに再エンコードし、すでにブロードキャストされたトランザクションのIDを変更できました。Mt. Goxは2014年2月に出金を停止し、まさにこの挙動のせいにしましたが、その後のチェーンの学術分析では、malleateされたトランザクションの量は消失したコインを説明するにはあまりにも少なすぎたことが判明しました。SegWitは2017年8月に、アンロック用データをIDの計算から完全に外すことでこの議論に決着をつけました。
署名スクリプトvsウィットネスデータ
署名スクリプトとウィットネスデータはどちらも同じ種類の証明を運び、SegWitは署名の意味を変えることなく、その役割を一方から他方へ移しました。利用者にとって重要な違いはコストと永続性です。ウィットネスのバイトは1バイトあたり1重量単位で計上されるのに対し、署名スクリプトのバイトは4重量単位かかるため、同じ単一鍵の支出でも、証明がscriptSigに入る場合はおよそ148仮想バイト、ウィットネスに入る場合はおよそ68仮想バイトになります。ウィットネスデータはトランザクションIDの外側にあるため、支出の識別子が転送中に改変されることはありません。レガシーのインプットは今も古いフィールドを使うため、1で始まるアドレスに置かれたコインは、動かすたびに静かにコストがかさみます。