你用一個 2-of-3 多簽錢包保管資產,現在要付一筆錢。打開錢包軟體,填好收款地址與金額,按下建立交易,畫面彈出一串 QR code 和一個 .psbt 檔案。你把它交給第一位共同持有人,對方接上硬體錢包、核對畫面、按下確認,回傳另一個 QR code;再交給第二位。兩份簽名湊齊,你按下廣播,交易才真正離開電腦,進入比特幣網絡的記憶池。
這條路徑許多人每個月都走一次,但中間那串以 cHNidP 開頭的字元到底是甚麼、為甚麼要這樣繞一圈,其實不少使用者從未弄清楚。PSBT部分簽名交易(Partially Signed Bitcoin Transaction)由 BIP-174 定義,逐步成為自我託管領域的通用中介格式,硬體錢包、多簽工具、冷錢包流程都建在它上面。這裡將其結構、角色分工、多人簽名的實際操作、最終化與廣播的每一步拆開解析,並點出容易踩中的技術陷阱。
甚麼情況下會碰到 PSBT
只要「建立交易」與「保管私鑰」發生在不同裝置上,PSBT部分簽名交易 就會出現在中間。日常最常遇到的三類場景:
- 硬體錢包簽名:電腦上的錢包軟體負責選幣、組裝交易、估算手續費,私鑰留在裝置裡。電腦把待簽內容交給裝置,裝置簽完回傳簽名。
- 多簽共管:2-of-3 或 3-of-5 的設定下,每個持有人手上只有一把私鑰。任何一筆支出都需要多人分別簽名,再把簽名拼起來。
- 冷熱分離:聯網機器負責與節點溝通、掌握 UTXO 狀態,離線機器或 air-gapped 裝置只做簽名。兩邊靠 QR code 或 SD 卡/USB 交換檔案。
反過來說,如果使用的是手機上的熱錢包,私鑰和組裝交易都在同一支應用裡完成,有些軟體內部依然會調用 PSBT 格式處理流水線,只是介面自動跑完了所有步驟,使用者完全看不到那串 Base64。PSBT 遂成為底層隱形的中介層。
PSBT 解決了甚麼核心問題
在 PSBT 標準確立之前,多簽的操作方式是把整筆原始交易交給每個簽名者,各自簽完再把簽名塞回交易結構裡。這條路徑上有三個根本痛點:
- 背景資料缺失:交易結構本身沒有地方放簽名者需要的背景資料。某個輸入對應的 UTXO 金額是多少、要用哪一段 redeem script 或 witness script、這把公鑰是沿著哪條推導路徑來的,這些都不在原始交易裡,過去只能靠自訂協定額外傳遞。
- 半成品無法自檢:只簽了一半的交易無法通過節點的腳本驗證,因此不能被當成一筆有效交易看待。
- TXID 不確定性:對 legacy 輸入來說,scriptSig 只要一被填入或修改,txid 就跟著改變,任何提前算好的交易識別碼都會失效。
PSBT 換了一個思路:保留一筆尚未填入任何簽名的交易骨架,把這筆骨架與簽名所需的全部背景資料一起裝進標準化容器。骨架放在全域欄位,每個輸入所需的 UTXO 金額、腳本、推導路徑放在各自的輸入欄位。這樣一來,任何支援 BIP-174 的裝置都能從檔案裡讀出「這筆交易要動用哪些幣、每個輸入屬於哪條推導路徑、該用哪種腳本簽」,不需要向對方追問,也不需要猜測。

檔案結構:鍵值對與 cHNidP 前綴
PSBT 的原始位元組以四個 magic bytes 開頭:0x70 0x73 0x62 0x74(ASCII 為 “psbt”),緊接一個 0xff 作為分隔。之後是一連串鍵值對,分成三個層次:
- 全域 Map:放整體資訊,最關鍵的是未簽名交易本身(key type
0x00),另外還有 xpub、PSBT 版本號、未知欄位等。 - 輸入 Map(每個輸入一個):放該輸入的來源資訊,例如
witness_utxo(SegWit 輸入只需這項)、non_witness_utxo(legacy 輸入需要完整的前一筆交易)、redeem script、witness script、BIP-32 推導路徑,以及簽名完成後的 partial signature。 - 輸出 Map(每個輸出一個):放找零輸出的腳本與推導路徑,讓簽名裝置能辨認「這筆錢是回到我自己的錢包」。
編碼上,鍵與值的長度前綴使用比特幣 compact size(varint)編碼,整數欄位採 little-endian。整個二進制結構做 Base64 編碼後,因為 magic bytes 的關係,任何 v0 的 PSBT 都會以 cHNidP 開頭。在通訊軟體或文件裡看到這串開頭,即可確認對方傳來的是 PSBT,而不是私鑰或助記詞。
六個角色構成的完整生命週期
BIP-174 將流程拆解為六個標準角色。在圖形化錢包中,單一軟體通常會同時扮演多個角色:
| 角色 | 負責的事 |
|---|---|
| Creator | 決定這筆交易要花哪些幣、付給誰、找零去哪,產出只有骨架的 PSBT。 |
| Updater | 補上每個輸入的 UTXO 資料、redeem script、witness script、推導路徑。 |
| Signer | 核對內容後產生簽名,寫入對應輸入的 partial signature 欄位。 |
| Combiner | 把多份各自簽了一部分的 PSBT 合併成一份,進行簽名集合聯集。 |
| Finalizer | 把 partial signature 搬進最終的 scriptSig 或 witness 欄位。 |
| Extractor | 抽出最終交易,序列化成可廣播的網絡格式。 |
建立階段:Creator 與 Updater 的協作
以 Bitcoin Core 的 RPC 指令為例,建立付款交易的常用指令為:bitcoin-cli walletcreatefundedpsbt '[]' '[{"bc1q...":0.01}]'。此指令同時實作了 Creator 與 Updater,自動選幣、估算手續費、補齊找零並填入節點已知的 UTXO 來源資訊。
若在離線環境下分步執行,則由 createpsbt 建立未經填充的骨架,再由聯網節點透過 utxoupdatepsbt 注入 UTXO 數據。使用 decodepsbt 可以還原為可讀的 JSON 結構,而 analyzepsbt 則會回傳當前交易還缺少的簽名角色與預估費率。
簽名階段:硬體裝置的自主核驗機制
將 PSBT 交給硬體錢包時,裝置會執行嚴格的驗證邏輯:
- 地址比對:用內部私鑰派生的公鑰與 PSBT 附帶的路徑進行比對,確認花費腳本合法。
- 金額與找零驗證:若 PSBT 附帶了完整前一筆交易(
non_witness_utxo),裝置可自行計算哈希並精確核對金額;若僅提供witness_utxo,裝置則核對該數值以計算手續費。若找零輸出屬於自身錢包,裝置會隱藏或標註為找零,防止找零被掉包。 - 檢查 sighash type:預設為
SIGHASH_ALL。若出現SIGHASH_NONE或SIGHASH_ANYONECANPAY,多數硬體會發出危險警告,因為這意味著其他人可以在事後篡改輸入或輸出。
簽名完成後,產生的簽名會暫存在 partial signature 欄位。此時交易尚未最終化,無法直接廣播。
多人簽名:傳遞、安全性與合併
在多簽協同中,簽名可以採取「接力式」(串行簽署)或「並行式」(各自簽署後由 Combiner 合併)。
針對協調者篡改交易的風險,防禦機制依賴各持有人在硬體螢幕上逐字核對目標地址與金額,或在簽署前核對 PSBT 全域未簽名交易的哈希指紋。
最終化、廣播與升級演進(v2 與 Taproot)
當收集齊足額簽名後,透過 combinepsbt 合併,再經由 finalizepsbt 將簽名置入 witness 結構。最後由 sendrawtransaction 發送到比特幣節點完成廣播。

在協定演進方面:
- PSBT v2(BIP-370):移除了全域未簽名交易欄位,改將交易版本、輸入輸出等拆成獨立鍵值對,允許在未組裝完整交易前逐步構造,降低硬體記憶體負擔。但需注意新舊版本在不同軟硬體間的兼容性。
- Taproot(BIP-371):擴展支援 Taproot 欄位(如
tap_internal_key、tap_leaf_script)。在結合 MuSig2 或 FROST 等方案時,可能需要多輪通信以交換 nonce,其 PSBT 交換流程會比傳統 ECDSA 多簽更具狀態依賴性。
常見排查與工具清單
- 缺少 UTXO 資訊:Legacy 交易若缺少完整
non_witness_utxo會被硬體拒絕,可用utxoupdatepsbt補齊。 - 簽名未生效:多數為漏掉 Finalizer 步驟,或錢包使用了萬用字元路徑導致硬體無法匹配私鑰。
- 合併失敗:若參與者修改了手續費或找零,底層交易骨架變更,標準實作(如 Bitcoin Core
combinepsbt)在偵測到未簽名交易不一致時會報錯拒絕合併。
| 工具名稱 | 定位與特點 |
|---|---|
| Bitcoin Core (CLI) | 提供完整 PSBT RPC 介面,適合腳本自動化與深度診斷。 |
| Sparrow / Specter | 專為硬體錢包多簽設計的桌面客戶端,視覺化解析 PSBT 結構與 QR code 交互。 |
| HWI / BDK | 底層開發庫與硬體橋接工具,適合開發者整合自訂多簽流程。 |
常見問題(FAQ)
Q1:PSBT 檔案如果不小心公開,資產會被盜走嗎?
不會。PSBT 內部不包含任何私鑰或助記詞,純粹持有 PSBT 無法動用資金。但它包含了錢包的 xpub、歷史交易關聯與金額,會造成嚴重的鏈上隱私洩露。
Q2:為甚麼簽署完成後不能直接拿到區塊鏈瀏覽器廣播?
因為簽名完成後的狀態屬於「部分簽名」,簽名數據存放在附加欄位中。必須經過 Finalizer(最終化)將簽名提取並寫入正式交易的腳本區塊,轉換為符合網絡格式的 Raw Transaction 才能廣播。
Q3:遇到手續費過低卡在記憶池,可以直接改 PSBT 來做 RBF 嗎?
不行。RBF(Replace-by-Fee)在密碼學上是一筆引用相同輸入但具有更高手續費的全新交易。一旦變更手續費或輸出,原有的簽名即宣告失效,必須重新建立 PSBT 並重新收集所有參與者的簽名。



