BIP-174: PSBT 部分簽章交易格式
定義標準格式用於傳遞未完成簽章的交易,支持多簽和硬體錢包。
174
Standards Track
Proposed
2017-07-12
摘要
PSBT(Partially Signed Bitcoin Transaction)定義了一種二進制格式,用於在多個參與方之間 傳遞未完成簽名的比特幣交易。這對於硬體錢包、多簽錢包和離線簽名工作流程至關重要。
動機
在比特幣交易簽名過程中,經常需要多方參與:
- • 硬體錢包:需要在離線設備上簽名
- • 多簽錢包:需要多個簽名者依次簽名
- • CoinJoin:需要多方協調輸入和輸出
- • 空氣隔離:需要通過二維碼或 USB 傳輸交易
PSBT 提供了一個標準格式,讓不同的錢包軟體可以互通操作。
PSBT 結構
一個 PSBT 由三個主要部分組成:
全局數據 (Global)
包含整個交易的通用信息,如未簽名的原始交易、擴展公鑰等。 這些數據對所有輸入和輸出都適用。
輸入數據 (Inputs)
每個輸入的詳細信息,包括前一筆交易、贖回腳本、見證腳本、 簽名、BIP-32 派生路徑等。
輸出數據 (Outputs)
每個輸出的詳細信息,包括贖回腳本、見證腳本、BIP-32 派生路徑等。 這對於找零地址的驗證很重要。
二進制格式
PSBT 使用鍵值對格式存儲數據:
<psbt> := <magic> <global-map> <input-map>* <output-map>*
<magic> := 0x70736274 0xFF ("psbt" + 分隔符)
<map> := <keypair>* 0x00
<keypair> := <key> <value>
<key> := <keylen> <keytype> <keydata>
<value> := <valuelen> <valuedata>
重要字段類型
全局字段
| 類型 | 名稱 | 描述 |
|---|---|---|
| 0x00 | UNSIGNED_TX | 未簽名的原始交易(必需) |
| 0x01 | XPUB | 擴展公鑰和其主指紋及路徑 |
| 0xFB | VERSION | PSBT 版本號 |
輸入字段
| 類型 | 名稱 | 描述 |
|---|---|---|
| 0x00 | NON_WITNESS_UTXO | 非 SegWit 輸入的完整前置交易 |
| 0x01 | WITNESS_UTXO | SegWit 輸入的 UTXO 資訊 |
| 0x02 | PARTIAL_SIG | 部分簽名(公鑰 → 簽名) |
| 0x03 | SIGHASH_TYPE | 簽名哈希類型 |
| 0x04 | REDEEM_SCRIPT | P2SH 的贖回腳本 |
| 0x05 | WITNESS_SCRIPT | P2WSH 的見證腳本 |
| 0x06 | BIP32_DERIVATION | 公鑰的 BIP-32 派生路徑 |
| 0x07 | FINAL_SCRIPTSIG | 最終的 scriptSig |
| 0x08 | FINAL_SCRIPTWITNESS | 最終的見證數據 |
工作流程
PSBT 定義了明確的角色和處理流程:
創建者 (Creator)
│
▼ 創建空白 PSBT
更新者 (Updater)
│
▼ 添加 UTXO 信息、腳本、派生路徑
簽名者 (Signer)
│
▼ 使用私鑰產生簽名
組合者 (Combiner)
│
▼ 合併多個部分簽名的 PSBT
完成者 (Finalizer)
│
▼ 生成最終的 scriptSig 和見證
提取者 (Extractor)
│
▼ 提取完整的簽名交易
角色說明
創建者 (Creator)
創建包含未簽名交易的 PSBT。設置輸入和輸出,但不填充任何簽名數據。
更新者 (Updater)
添加簽名所需的信息:UTXO 數據、贖回腳本、見證腳本、BIP-32 派生路徑等。 可以有多個更新者,每個添加自己知道的信息。
簽名者 (Signer)
驗證 PSBT 數據,使用私鑰產生簽名,將簽名添加到對應輸入的 PARTIAL_SIG 字段。 簽名者可以是硬體錢包或軟體錢包。
組合者 (Combiner)
將多個部分簽名的 PSBT 合併成一個。對於多簽交易,這一步驟收集所有需要的簽名。
完成者 (Finalizer)
使用收集的簽名構建最終的 scriptSig 和見證數據。 這一步驟確保所有輸入都有完整的解鎖腳本。
提取者 (Extractor)
從完成的 PSBT 中提取可廣播的原始交易。 這是工作流程的最後一步。
實際應用範例
硬體錢包簽名
# 1. 軟體錢包創建 PSBT
bitcoin-cli walletcreatefundedpsbt '[]' '[{"bc1q...": 0.01}]'
# 2. 導出為 Base64 格式
bitcoin-cli walletprocesspsbt "cHNidP8B..."
# 3. 在硬體錢包上簽名(通過 USB 或二維碼傳輸)
# 4. 導入已簽名的 PSBT
bitcoin-cli finalizepsbt "cHNidP8B..."
# 5. 廣播交易
bitcoin-cli sendrawtransaction "0200000001..."
2-of-3 多簽工作流程
# 協調者創建 PSBT
psbt_base64 = create_psbt(inputs, outputs)
# 簽名者 A 簽名
psbt_signed_a = signer_a.sign(psbt_base64)
# 簽名者 B 簽名(可以並行進行)
psbt_signed_b = signer_b.sign(psbt_base64)
# 組合兩個簽名
psbt_combined = combine([psbt_signed_a, psbt_signed_b])
# 完成並提取交易
final_tx = finalize_and_extract(psbt_combined)
安全優勢
PSBT 讓簽名者可以在離線環境中驗證交易的完整細節: 發送金額、接收地址、手續費等,然後再決定是否簽名。 這大大降低了被惡意軟體欺騙簽署意外交易的風險。
PSBT 版本 2
BIP-370 定義了 PSBT 版本 2,增加了新功能:
- • 更好的構建過程 , 可以在不知道所有輸入的情況下添加輸出
- • 支持交易修改器角色
- • 更靈活的 CoinJoin 和 PayJoin 支持
相關 BIP
相關 BIP
延伸閱讀: 查看 GitHub 上的完整 BIP-174 文件