Bitcoin Scriptは支出条件を表す言語です。トランザクションの各出力、つまり次に使うための条件が付いた金額には、その条件が記録されています。使いたい人はそれを満たす必要があります。Scriptが答えるのは、このトランザクションがこの特定の資金を使ってよいか、という素朴な問いです。
Aliceは20 000 sat、つまり二万satoshiを受け取ります。satoshiはビットコインの最小単位です。ネットワークにAlice名義の口座ができるのではありません。作られるのはトランザクションの出力、つまり金額と後で使うための条件です。まだ使われていない出力をUTXOと呼びます。一般的な支払いでは、対応する鍵による署名が条件になります。Aliceが後で支払うとき、ウォレットはこの出力を選び、新しいトランザクションの入力で参照し、デジタル署名を作ります。秘密鍵を使いますが、それを誰かに送ることはありません。他の人は公開鍵で署名を検証します。Aliceの受取アドレスを知っているだけでは足りません。元の出力の条件はscriptPubKeyというフィールドに記録され、Bitcoin Scriptが条件の成立を確かめる方法を定めます。ノードはAliceの顔を知る係員ではなく、ルールを確認するコンピューターです。署名のほかにも、同じ出力がすでに使われていないかなどを確認します。関係するすべてのルールを満たして初めて、トランザクションは有効になります。 [4] [2]
通常の支払いでは、ウォレットが条件を組み立てます。そのウォレットの説明に従ってバックアップしてください。互換性のあるウォレットでバックアップの単語から通常の復元を行う際、すべてのスクリプトを手作業で保存する必要があるとは限りません。一方、複数の署名を必要とするMultisigなどの複雑な構成では、一人分の単語だけで支出の仕組み全体を再現できないことがあります。 普段使いには、十六進表記でスクリプトを手作業で組み立てるより、検証された手順を備えるウォレットが適しています。出力ディスクリプターは、スクリプトの種類、鍵、鍵の導出方法を記述し、復元したウォレットが何を探すべきかを特定する助けになります。複雑な構成を復元するには、秘密鍵だけでは足りない場合があります。必要なスクリプトと、鍵がどこからどのように導出されたかを示す情報も保管し、想定する支出経路を検証してください。 [11]
ここからは、トランザクション内部で条件をどう記録するかを見ていきます。日常の支払いにこの知識は必須ではありません。scriptSigフィールドとwitnessという部分が検証用のデータを渡します。ハッシュはデータの指紋に当たり、タイムロックは決められた境界より前の支出を禁止します。スタックは、上から出し入れするデータの山と考えると分かりやすくなります。 Script はスタックを使ってデータを処理します。値を積み込み、オペコードと呼ばれる命令がそれを取り出したり、比較したり、その他の処理を行ったりします。署名に関する命令は署名を検証するものであり、秘密鍵を扱ったり署名を作ったりする処理は、この検証には含まれません。署名、ハッシュ条件、タイムロックを組み合わせることができますが、汎用的なループはなく、チューリング完全ではありません。つまり、汎用プログラミング言語で表現できるあらゆる計算を記述できるわけではありません。ノードは出力の種類とスクリプトのバージョンに対応する、厳密なルールを適用しなければなりません。 [1] [3]
P2PKH (Pay to Public Key Hash) の出力は通常、OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG という形です。入力は scriptSig で署名と公開鍵を渡します。検証では公開鍵のハッシュが出力内の値と一致するかを調べ、その後に署名を検証します。そのため、アドレスや公開鍵を知っているだけでは、その出力を使うことはできません。秘密鍵を使うのは署名するウォレットであり、トランザクションを検証するノードではありません。 [1]
P2SH は BIP16 に従い、スクリプトのハッシュを出力に格納します。支出する入力は、支出時に公開する対応したスクリプト redeemScript と、必要なデータを提示します。scriptSig に入れられるのは、データを積み込む命令だけです。ノードは最初にハッシュの一致を確認し、その後に残りのスタック項目を使って redeemScript を評価します。ハッシュが正しいだけでは支出できず、そのスクリプトの条件も満たす必要があります。 [5]
SegWit バージョン 0 では、検証用のデータが witness と呼ばれるトランザクションの領域に移ります。これはデータ項目の一覧であり、それ自体がスクリプトなのではありません。P2WPKH は署名と公開鍵を使い、P2WSH はさらに witnessScript を含みます。その SHA256 ハッシュは出力と一致しなければなりません。ネイティブ SegWit では scriptSig は空です。P2SH で包む場合、scriptSig には対応する witness プログラムを積み込む命令だけが入り、実際の検証用データは witness に残ります。 [6]
署名の検証は、決められた手順でトランザクションから導いたメッセージを対象にします。SIGHASH モードによって、トランザクションのどの部分を署名が変更から守るかが決まります。したがって、すべての署名が必ずトランザクション全体を保護すると考えることはできません。BIP143 は、SegWit バージョン 0 の署名処理に、使おうとする出力の金額を常に含めます。ウォレットは正しいデータと選択したモードを把握する必要があります。Script は検証時に、署名した人の意図までは判断しません。 [7]
BIP341 で定められた Taproot では、P2TR (Pay to Taproot) 出力を二つの方法で使えます。鍵経路では、スクリプトを公開せずに、出力の公開鍵に対して Schnorr 署名を検証します。一方、スクリプト経路では、選んだスクリプトと、その出力との結び付きを証明する制御ブロック、つまり control block を公開します。木に含まれる他のスクリプトを公開する必要はありません。公開したスクリプトに適用するルールは、対応する葉のバージョンにも依存します。 [8]
BIP342 は、バージョン 0xc0 の Taproot の葉に対して Tapscript を定義しています。ここで署名を扱う命令は Schnorr 署名を使い、OP_CHECKSIGADD によって複数の署名を要求する条件を組み立てられます。従来の OP_CHECKMULTISIG を実行すると、スクリプトの検証は失敗します。以前のスクリプト長の上限である 10 000 バイトや、旧ルールで数える 201 オペコードという上限は引き継ぎません。署名処理の回数は witness のサイズから決まる予算で制限され、スタックの制限は引き続き存在します。そのため、一つのバージョンの制限を Script 全体の一般的な性質として扱ってはいけません。 [9]
コンセンサスルールは、ブロック内の支出が有効かどうかを定めます。取引の標準性とは、ノードが未承認トランザクションを Mempool に受け入れ、中継するために追加で適用するローカルなルールのことであり、標準化を進める作業ではありません。したがって、コンセンサス上は有効な取引でも、通常は中継されない場合があります。Tapscript の OP_SUCCESSx には特に注意が必要です。先行する検査に成功した後、デコード中にこれを認識すると、通常の実行やスタックの検査に進む前に、スクリプトの検証は成功として終了します。これは将来の拡張のための余地であり、通常の安全な支出条件ではありません。 [10] [9]
理解を深めるには、この項目とあわせて次もお読みください トランザクション, Multisig, Timelock, Taproot. 次の項目からも参照されています Hash, SHA-256, コンセンサスルール, Timelock.