一文看清 PSBT 部分簽名交易:由建立、多人簽名到廣播的完整流程

一文看清 PSBT 部分簽名交易:由建立、多人簽名到廣播的完整流程
字号
【导读】PSBT 部分簽名交易(BIP-174)為何成為硬體錢包與多簽的中介格式?本文拆解 cHNidP 檔案結構、Creator 到 Extractor 六大角色、硬體簽名核驗、多人簽名合併、最終化廣播,以及 PSBT v2 與 Taproot 的演進與常見排查。

你用一個 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 標準確立之前,多簽的操作方式是把整筆原始交易交給每個簽名者,各自簽完再把簽名塞回交易結構裡。這條路徑上有三個根本痛點:

  1. 背景資料缺失:交易結構本身沒有地方放簽名者需要的背景資料。某個輸入對應的 UTXO 金額是多少、要用哪一段 redeem script 或 witness script、這把公鑰是沿著哪條推導路徑來的,這些都不在原始交易裡,過去只能靠自訂協定額外傳遞。
  2. 半成品無法自檢:只簽了一半的交易無法通過節點的腳本驗證,因此不能被當成一筆有效交易看待。
  3. TXID 不確定性:對 legacy 輸入來說,scriptSig 只要一被填入或修改,txid 就跟著改變,任何提前算好的交易識別碼都會失效。

PSBT 換了一個思路:保留一筆尚未填入任何簽名的交易骨架,把這筆骨架與簽名所需的全部背景資料一起裝進標準化容器。骨架放在全域欄位,每個輸入所需的 UTXO 金額、腳本、推導路徑放在各自的輸入欄位。這樣一來,任何支援 BIP-174 的裝置都能從檔案裡讀出「這筆交易要動用哪些幣、每個輸入屬於哪條推導路徑、該用哪種腳本簽」,不需要向對方追問,也不需要猜測。

PSBT部分簽名交易的容器結構示意圖,包含交易骨架、輸入元數據與標準化封裝模組
PSBT部分簽名交易將交易骨架與各輸入項所需的背景數據集中封裝於標準容器中,使離線與多方設備能獨立解析簽名需求。

檔案結構:鍵值對與 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 雖然不含私鑰,但包含 UTXO 明細、金額、腳本以及未硬化路徑的帳戶 xpub。一旦公開外洩,第三方可推導出該帳戶所有的歷史與未來地址,導致資產完全透明。因此傳遞 PSBT 應使用加密渠道。

針對協調者篡改交易的風險,防禦機制依賴各持有人在硬體螢幕上逐字核對目標地址與金額,或在簽署前核對 PSBT 全域未簽名交易的哈希指紋。

最終化、廣播與升級演進(v2 與 Taproot)

當收集齊足額簽名後,透過 combinepsbt 合併,再經由 finalizepsbt 將簽名置入 witness 結構。最後由 sendrawtransaction 發送到比特幣節點完成廣播。

多方協同完成 PSBT部分簽名交易 的並行簽署、合併驗證至節點廣播全流程
各簽名節點獨立完成部分簽名後,經由合併器匯總並由最終化模組寫入見證數據,轉換為標準網絡交易進行廣播。

在協定演進方面:

  • 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 並重新收集所有參與者的簽名。

admin

作者负责资讯整理、核查与撰写。 · 已发布 93 篇文章

查看作者全部文章