PSBT v2 は、Partially Signed Bitcoin Transaction、つまり部分的に署名された Bitcoin トランザクション形式の、仕様で定められた二番目のバージョンです。BIP 370 が定義する、ウォレットと署名機器に共通の作業用形式であり、署名がまだない案も格納できます。複数の参加者による構築を助けますが、それぞれの確認や Bitcoin ネットワークのルールに取って代わるものではありません。
アンナとヤンは、一枚の請求書を一緒に支払おうとしています。それぞれが資金の一部を出し、自分の機器で署名を加えます。交換すべきなのは合意した取引案であって、秘密鍵ではありません。秘密鍵は、ウォレットが資金の使用を承認する電子署名を作るための秘密の数値です。PSBT はトランザクションと補足情報を入れた作業用の封筒として機能します。入力は使用する以前の金額を指し、出力は新しい金額と、その後に使うための条件を定めます。従来の PSBT v0 は、この骨組みを固定されたグローバルな未署名トランザクションとして保持します。v2 では、対応するルールに従って入力と出力を順に追加できます。利点は共同で構築できることであり、誰かが署名した内容を自由に書き換えられることではありません。 [1] [2]
アンナがすべての技術フィールドを読む必要はありません。ただし、信頼できる署名機器で本当の送金先、金額、手数料、自分のウォレットに戻るお釣りを確認する必要があります。最後の項目は見落としがちです。他人の出力を自分へのお釣りと思い込んではいけません。機器は UTXO、つまりまだ使われていない出力の情報を検証し、その条件と署名対象が一致するかを確かめます。鍵の導出パスは、ウォレットがマスター鍵から特定の鍵を求める手順を示します。そのパスがファイルに書かれているだけでは、資金が自分のものだとは証明できません。署名機器は、署名がトランザクションのどの部分を保護するかを指定する SIGHASH も正しく解釈する必要があります。署名のために、交換するファイルへ秘密鍵やウォレットのバックアップ用の単語列である Seed Phrase を加える必要はありません。 [2] [4]
機器やアプリが PSBT 対応をうたっていても、v2 に対応しているとは限りません。具体的なソフトウェアと機器の間で、作成、取り込み、署名、結果の返却まで一通り確認する必要があります。PSBT v0 と v2 はそのまま交換できません。v0 への変換には未署名トランザクションを構築し、そのバージョンのルールに合わせてフィールドを調整する必要があります。数字を書き換えるだけでは不十分です。Bitcoin の出力を使う条件を定める新しい方式である Taproot も、v2 と同じものではありません。BIP 371 は、その署名情報を両方の PSBT バージョン向けに定義しています。少額での一連の試行は、その組み合わせの互換性を確かめますが、将来のすべての支払いの正しさまでは保証しません。 [1] [3]
ファイル形式のバージョンと Bitcoin トランザクションのバージョンは、意味が異なります。v2 では PSBT_GLOBAL_VERSION が 2 でなければならず、古い PSBT_GLOBAL_UNSIGNED_TX フィールドは存在してはいけません。別の必須フィールド PSBT_GLOBAL_TX_VERSION がトランザクション自体のバージョンを指定します。入力数と出力数も必須です。この分離により、各項目の情報をその項目にまとめられ、プログラムが共通の骨組みも探す必要がなくなります。作成者が後の構築を他の参加者に任せる場合、BIP 370 は適切な変更フラグと、少なくとも 2 のトランザクションバージョンを要求します。あくまで作業用形式であり、ネットワークの新しい合意ルールではありません。 [1]
各入力には、以前のトランザクションの識別子である TXID と、その中のどの出力を使うかを示すインデックスが必要です。一つのトランザクションに複数の出力があるため、TXID だけでは足りません。新しい各出力は、Bitcoin の最小単位である satoshi で表した金額と、使用条件を定めるスクリプト scriptPubKey を持ちます。項目を追加したら、対応する全体の件数も更新します。任意の sequence フィールドには入力の別の制御値が入り、省略時には 0xffffffff を使います。これらは組み立て方を示すデータです。署名や手数料を安全に判断するために必要な、使用する UTXO の金額と使用条件の情報を代替するものではありません。 [1]
ヤンが入力を追加したくなったとします。プログラムはファイルを持っているというだけで、追加が許されると思い込んではいけません。PSBT_GLOBAL_TX_MODIFIABLE のビット 0 は入力を変更できるか、ビット 1 は出力を変更できるかを示します。ビット 2 は、入力と対応する位置の出力を組にする SIGHASH_SINGLE 署名があることを示します。他の項目を挿入しても、この組み合わせを保たなければなりません。そのため、構築する側は実際の署名と制約を確認します。フラグは協力するプログラムに情報を伝えるものであり、暗号学的な署名を迂回したり、無効な変更を有効にしたりはできません。 [1]
入力によっては、特定のブロック高や時刻の境界を過ぎるまでトランザクションを使わないよう要求します。ブロックはネットワークの共通の履歴に記録されるトランザクションのまとまりで、ブロック高はチェーン内の位置を表します。共通の nLockTime は、すべての入力と両立する種類の条件を使う必要があります。その種類の中で最も大きい要求値を選び、両方の種類が可能ならブロック高を優先します。高さと時刻を普通の二つの数字として比較することはできません。どの入力も条件を持たない場合はグローバルな代替値を使い、それもなければ 0 を使います。両立しない条件の入力は追加できません。すでに署名があるなら、新しい入力によって算出済みの nLockTime を変えることもできません。これらのフィールドだけで、すべてのタイムロック規則への適合が保証されるわけではありません。 [1]
署名が加わると、その後の変更の自由が狭まります。BIP 370 では、SIGHASH_ANYONECANPAY を使わない署名では入力の変更を、SIGHASH_NONE を使わない署名では出力の変更を無効にし、SIGHASH_SINGLE では維持すべき組を記録します。これらの名前は署名の保護範囲を表し、初心者が無作為に切り替える設定ではありません。すべての入力が準備できたら、最終化で必要な署名データを組み立て、抽出処理が各フィールドからネットワーク形式のトランザクションを作ります。送信して初めてノードが評価し、マイナーがブロックへ収録できます。アンナとヤンは取引案、署名済みの結果、確認済みの支払いを区別します。PSBT を渡すだけでは、署名や確認を行ったことにはなりません。 [1] [2] [4]
理解を深めるには、この項目とあわせて次もお読みください PSBT, Hardware Wallet, Multisig, Taproot, Bitcoin, UTXO.