拆解比特幣PSBT

一、什么是 PSBT
1、PSBT
部分簽名的比特幣交易(PSBT)是一種用于構(gòu)建和處理比特幣交易的描述格式,它提供了一種安全且靈活的方式,使多個參與方能夠協(xié)同工作,構(gòu)建和簽名比特幣交易,而無需將私鑰暴露給其他人。PSBT 標準定義了用來傳遞比特幣交易的一種精確格式,可以攜帶一筆交易的元數(shù)據(jù),并使它們可以在多個設(shè)備之間傳遞讓簽名者更容易簽名和驗證這筆交易,以便不同的參與者可以對其進行簽名。
2、流程概述
構(gòu)建一筆完整簽名的比特幣交易比較復(fù)雜,我們可以簡化角色為:創(chuàng)建者、簽名者、協(xié)調(diào)員。我們以 Alice、Bob 和 Charlie 之間的一筆交易為例。Alice、Bob 和 Charlie 有一筆 UTXO 存在一個 2/3 的多簽中,他們想把這筆錢取出并均分為 3 份,他們?nèi)吮仨毢炇鹜粋€交易去花費這個UTXO。
假設(shè)他們互不信任,他們需要怎么做才能保證資金安全呢?
首先,Alice 作為創(chuàng)建者發(fā)起一個 PSBT 交易,多簽的 UTXO 作為輸入,輸出是三人各自的錢包地址。由于 PSBT 保證了除此交易外的其他交易都無法調(diào)用任何一人的簽名,所以 Alice 可以簽完名后發(fā)給 Bob。
同樣,Bob 檢查 PSBT 后,如果覺得沒問題也進行簽名;簽名后給到 Charlie 進行簽名和交易發(fā)布。Charlie 也進行同樣的操作。
Partially signed,其實就是解決了每個人只需要檢查跟自己相關(guān)的那部分交易,只要和自己相關(guān)的交易沒問題就能保證交易上鏈后不會有問題。為了上述流程的高效,之后引入了「協(xié)調(diào)員」這個角色。協(xié)調(diào)員作為一個中心化聚合節(jié)點,分別給 A、B、C 發(fā)送交易三個同樣的交易讓他們簽名確認,隨后將三個簽名后的交易合并后上鏈,提高了 PSBT 流程的效率。
舉個例子,五位參與者要建構(gòu)一筆 CoinJoin 交易,他們各自給一位協(xié)調(diào)員發(fā)送一條消息,包含自己希望放入這筆 CoinJoin 中的?UTXO。每個參與者也都提供接收比特幣的地址。
協(xié)調(diào)員實用所有的 UTXO 作為輸入,建構(gòu)出一筆交易,并創(chuàng)建相應(yīng)的輸出,將相同數(shù)量的比特幣發(fā)到各參與者的接收地址。
下一步,協(xié)調(diào)員將這筆交易轉(zhuǎn)化成一個部分簽名的比特幣交易,然后將這個 PSBT 發(fā)送給每一位參與者。參與者們各自為自己收到的 PSBT 加入自己的簽名,然后將簽過名的 PSBT 發(fā)回給協(xié)調(diào)員,協(xié)調(diào)員會將這 5 個 PSBT 合并起來、形成最終的交易。最終,協(xié)調(diào)員得到了一個完整簽名的交易,每個參與者的輸入都有相應(yīng)的簽名。
這個過程是完全免信任的:雖然每個成員都依賴于協(xié)調(diào)員來創(chuàng)建和敲定 PSBT,無論協(xié)調(diào)員還是參與者,沒有人能從其他參與中手上偷取資金。
二、PSBT 實現(xiàn)方案
1、細節(jié)流程
- 一位創(chuàng)建者提出需要創(chuàng)建的某一筆交易。他們構(gòu)造一個 PSBT,包含特定的輸入和輸出,但不包含其它元數(shù)據(jù)。
- 對每個輸入,都由一位更新者為該 PSBT 加入關(guān)于被花費的 UTXO 的信息。他們也在該 PSBT 的每一個輸入(可能的時候包括輸出)中加入關(guān)于腳本和公鑰的信息。
- 簽名者檢查交易及其元數(shù)據(jù),來決定是否同意該交易。他們可以利用來自 UTXO 的數(shù)額信息,知曉相關(guān)的價值和手續(xù)費。如果他們同意,就為自己具有相關(guān)公鑰的輸入生成一個「部分簽名」。
- 為每個輸入運行一個定稿器,將「部分簽名和可能的腳本信息轉(zhuǎn)化為一個最終的?
scriptSig
?(腳本簽名)以及/或者?scriptWitness
?(腳本見證數(shù)據(jù))。 - 抽取器從各輸入已經(jīng)定稿的 PSBT 中產(chǎn)生一筆有效的比特幣交易(變成可在網(wǎng)絡(luò)中廣播的形式)。
一般來說,上述的每一個流程(除了創(chuàng)建者和抽取器)都會為處理中的 PSBT 加入越來越多的數(shù)據(jù),直至所有輸入都被簽名。在一個粗疏的工作流中,他們必須按照順序、一個接一個地參與,直到抽取器將 PSBT 轉(zhuǎn)化為一筆真實的交易。為了允許「并行」操作,可以增加一個合并者,由 TA 來為同一筆未簽名的交易合并來自不同 PSBT 的元數(shù)據(jù)。
2、具體實現(xiàn)(以?Bitcoin Core 為例)
Alice、Bob 和 Carol 希望創(chuàng)建一個 2-of-3 的多簽名地址。他們都使用 Bitcoin Core。我們假設(shè)他們的錢包中只包含多簽名資金。與此同時他們各有一個個人錢包,這可以通過 Bitcoin Core 的多錢包特性來實現(xiàn) —— 可能因此在使用命令行工具 bitcoin-cli 時需要使用?rpcwallet=name
?來指明調(diào)用哪個錢包。
2.1 創(chuàng)建多簽地址
- 生成地址:三人各使用?
getnewaddress
?來創(chuàng)建一個新地址;我們把這三個地址分別叫做?Aalice、Abob?和?Acarol。生成新地址是為了確保交易的隱私和安全性。 - 生成公鑰:三人各自調(diào)用?
getaddressinfo "X"
?,X 就是他們各自的地址,并記錄相應(yīng)的公鑰;我們把這幾個公鑰分別叫做?Kalice、Kbob?和?Kcarol。 - 生成多簽地址:三人可以各自運行?
addmultisigaddress 2 ["Kalice","Kbob","Kcarol"]
?以產(chǎn)生多簽名腳本并告知錢包模塊;這條命令所產(chǎn)生的多簽名地址,我們叫做?Amulti?。他們可以需要手動指定相同的地址類型,以免因為不同的節(jié)點設(shè)置而建構(gòu)出不同版本的地址。各自運行的原因是為了實現(xiàn)并行地簽名同一筆交易。 - 監(jiān)測多簽地址:他們還各自運行?
importaddress "Amulti" "" false
?,命令錢包跟蹤?Amulti
?所收到的支付并作為觀察錢包余額。 - 檢驗地址是否正確:其他人可以通過運行?
createmultisig 2 ["Kalice","Kbob","Kcarol"]
?、檢查結(jié)果是否為?Amulti?來驗證這個地址。同上,可能有必要指定地址類型,才能獲得匹配的地址。不過,這個命令不能用來初始化交易。
2.2 PSBT使用多簽地址
他們現(xiàn)在可以對外給出?Amulti,作為其他人可以支付的地址。當?Amulti?收到 V BTC 之后,Bob 和 Carol 想把資金全部移到?Asend,沒有找零。Alice 不需要參與。
- 其中一人 —— 這里假設(shè)是 Carol —— 初始化創(chuàng)建流程。她運行?
walletcreatefundedpsbt [] {"Asend":V} 0 {"subtractFeeFromOutputs":[0], "includeWatching":true}
?。我們把這個命令所返回的 PSBT 叫做?P。P?不包含任何簽名。 - Carol 需要自己簽名這筆交易。為此,她運行?
walletprocesspsbt "P"
?,然后將結(jié)果?P2?(也是一個 PSBT)交給 Bob。 - Bob 使用?
decodepsbt "P2"
?來檢查這個 PSBT,確認這筆交易是否有預(yù)期的輸入、有一個輸出給?Asend、手續(xù)費合理。如果他也同意這筆交易,他調(diào)用?walletprocesspsbt "P2"
?來簽名。結(jié)果是?P3,包含了 Carol 和 Bob 的簽名。 - 現(xiàn)在,任何一人都可以調(diào)用?
finalizepsbt "P3"
?,抽取出完整簽名的交易?T。 - 最后,任何人都可以使用?
sendrawtransaction "T"
?來廣播這筆交易。
2.3 并行操作
在需要更多簽名者參與的情形中,讓所有者并行簽名而不是按順序處理可能會有一些好處。在我們的例子中,就會變成 Carol 分別給每個簽名者傳遞?P?的拷貝;簽名者各自調(diào)用?walletprocesspsbt "P"
?來簽名,最終得到各自簽名的 PSBT 結(jié)構(gòu)體。然后,他們將各自的 PSBT 結(jié)構(gòu)體發(fā)回給 Carol(發(fā)給其他某一人也可以),由后者來運行?combinepsbt
?。最后的兩個步驟(?finalizepsbt
?和?sendrawtransaction
?)保持不變。
3、PSBT 有什么用處
PSBT 給比特幣社區(qū)提供了許多好處,也讓此前的復(fù)雜協(xié)議得到簡化,變得更容易驗證。
- 互通性。PSBT 的設(shè)計初衷是強化錢包和其它比特幣軟件的互通性,讓交易可以更容易地在錢包和節(jié)點間傳輸。PSBT 在很大程度上已經(jīng)成功了,它獲得了所有主要的錢包供應(yīng)商和節(jié)點軟件的支持,也就是已經(jīng)得到了行業(yè)的接受。
- 離線簽名。PSBT 格式提供了有用的元數(shù)據(jù),可以協(xié)助冷存儲設(shè)備驗證即將被簽名的交易相關(guān)的地址和金額。這使得從冷存儲設(shè)備發(fā)起簽名變得更加安全,而且?觀察錢包構(gòu)造交易-冷錢包簽名-比特幣節(jié)點廣播交易 的整個過程也變得更加容易。
- 多簽名流程。因為 PSBT 讓一個部分簽名的比特幣交易變得更容易傳輸和理解,多方(或者說多個設(shè)備)簽名一筆交易也變得更容易、更安全,因此多簽名技術(shù)也變得更容易使用。用戶友好型多簽名錢包將給比特幣社區(qū)帶來進一步的好處,包括更好的隱私性、安全性和私鑰丟失抗性。
- 多方交易。PSBT 對想要簽名同一筆交易的協(xié)作多方尤為實用。比如,CoinJoin、CoinSwap?和?PayJoin?協(xié)議,都要求多方簽名同一筆交易。PSBT 格式提供了構(gòu)造交易、在多個簽名者之間傳輸交易、組裝成最終交易的方法。
三、去中心化 Marketplace 探索
當前,比特幣 NFT 的一大問題就是交易門檻極高,如果不通過?Ordinals?橋接至以太坊網(wǎng)絡(luò),并在 OpenSea 上交易,就只能通過 OTC 的渠道進行買賣。但 OTC 最大的問題就是需要信任,目前是缺少交易信息和信任渠道的。PSBT 在比特幣 NFT 發(fā)展中扮演的角色,就是在沒有智能合約的情況下,實現(xiàn)交易的去信任化。
假設(shè)現(xiàn)在有一對比特幣 NFT 交易者,且 NFT 賣方的公鑰是雙方可知的信息。在發(fā)起一筆 NFT 交易時,買方先在交易中寫好自己的 UTXO 輸入以及一個承接 NFT 的輸出。買方在構(gòu)建好交易并簽名后,將其轉(zhuǎn)為 PSBT 發(fā)給賣方,賣方通過中間服務(wù)商等方式接收到消息后簽名,這筆比特幣 NFT 交易就成交了。
上述整個過程對買賣雙方而言都是完全去信任的。對于買方來說,出價、接受地址等信息已經(jīng)提前構(gòu)建在交易中,一旦發(fā)生改動,簽名便會失效。對于賣方來說,只有自己完成簽名,NFT 才會賣出,而價格則是經(jīng)過自己審核衡量的。在阿劍看來,這種簡單的交易結(jié)構(gòu)還在很大程度上剔除了 OpenSea、Blur 這類 NFT 交易中間服務(wù)商的抽成空間,「只要賣方的消息渠道通暢,就完全不需要中介,因為買方簽好名的交易直接就是出價」。
現(xiàn)如今,PSBT 已經(jīng)被廣泛應(yīng)用于多方簽名、硬件錢包、CoinJoin 交易、閃電網(wǎng)絡(luò)等領(lǐng)域。以下是一些 PSBT 的應(yīng)用案例:
- 多方簽名:PSBT 可以用于多方簽名的比特幣交易,以確保交易的安全性和可靠性。
- 硬件錢包:PSBT 可以用于硬件錢包中,以便在不暴露私鑰的情況下,構(gòu)建和簽名比特幣交易。例如用公開錢包構(gòu)建交易,只用硬件錢包簽署 PSBT 。
- CoinJoin 交易:PSBT 可以用于 CoinJoin 交易中,以便將多個交易合并為一個交易,從而提高交易的隱私性。
- 閃電網(wǎng)絡(luò):在創(chuàng)建支付通道時,需要使用 PSBT 來構(gòu)建和簽名比特幣交易,以便將比特幣存入支付通道中;在使用支付通道進行交易時,需要使用多重簽名技術(shù)和 PSBT 來簽名交易