如何在一次交易中從多個錢包中花費比特幣?
例如,使用 Bitcoin Core 命令行,我如何在一次交易中從多個錢包中花費比特幣?
這條評論說:
您無需將交易發送到網路,而是將其發送給下一個將添加其輸入和輸出並對其進行簽名的人,依此類推。最後一個人將在網路上廣播交易。
我假設我使用
createrawtransaction
andsignrawtransaction
不知何故,但我究竟是如何做到這一點的?參看。掌握比特幣(第 1 版),§“從命令行使用 Bitcoin Core 的 JSON-RPC API”,§§“基於未使用的輸出創建、簽名和送出交易”
目前有三種不同的方法可以做到這一點:原始交易、0.17 中的 PSBT 和 0.18 中的 PSBT。我建議你在 0.18 中使用 PSBT,因為它最省事,但我會在這里為你描述所有這三個。
傳統上,您會使用
createrawtransaction
、fundrawtransaction
和signrawtransactionwithkey
/來執行此操作signrawtransactionwithwallet
。一個人必須知道交易中使用的所有輸入或將所有輸入儲存在他們的錢包中(即他們已經將其他所有人的公鑰和/或redeemScripts導入到他們的錢包中),然後他們可以使用createrawtransaction
或fundrawtransaction
創建原始交易。
createrawtransaction
只需接受使用者指定的輸入和輸出,並按原樣提供結果交易(因此您需要注意費用和更改)。fundrawtransaction
可以使用您的錢包為您選擇要使用的輸入,它會自行處理費用並更改輸出。但是fundrawtransaction
需要知道建構最終交易所需的所有資訊(私鑰除外,它可以只使用一個虛擬簽名)才能正確估計交易費用,這就是您需要導入公鑰和腳本的原因進你的錢包。一旦您有了原始交易,您就可以將其發送給參與交易的其他每個人。然後他們使用
signrawtransactionwithwallet
(如果密鑰和腳本在他們的錢包中)或signrawtransactionwithkey
(如果他們的密鑰和腳本不在他們的錢包中)對其進行簽名。大多數人都會使用signrawtransactionwithwallet
. 然後他們將結果發回給您,您必須使用 .將所有已簽名的交易合併到最終交易中combinerawtransaction
。然後你可以用 廣播它sendrawtransaction
。與其將交易同時發送給每個人進行簽名,您可以發送給一個簽名的人,然後再發送給下一個人,依此類推。這不需要
combinerawtransaction
. 最後一個人會簽名,然後sendrawtransaction
用來廣播。這個過程有點龐大,需要一個人知道正在使用的輸入的部分(或全部)資訊(私鑰除外)。
從 Bitcoin Core 0.17 開始,您可以使用各種
*psbt
RPC 來實現相同的目標。使用 0.17 時,流程與前面描述的原始事務流程非常相似。您必須擁有在您的錢包中創建最終交易的所有資訊(私鑰除外),以便可以正確估算硬幣選擇的費用,或者您需要知道要使用哪些輸入。無論哪種方式,您都可以使用walletcreatefundedpsbt
並指定所需的輸入和所需的輸出。如果沒有足夠的輸出量,Bitcoin Core 會自動選擇額外的輸入並為你創建一個找零輸出。因為它還需要轉換交易費用,所以它需要具有您所需的相同資訊,fundrawtransaction
以便能夠估算其選擇的輸入的費用。然後,您將把交易發送給其他所有人,他們將使用
walletprocesspsbt
. 您也可以walletprocesspsbt
在將交易發送給所有人之前先執行此操作,以便預先添加簽名所需的各種元數據(例如用於每個輸入的 UTXO)。簽名後,每個人都會將交易發回給您,然後您將它們組合在一起使用combinepsbts
然後您創建最終交易以用於廣播finalizepsbt
並使用發送結果sendrawtransaction.
當然,使用 PSBT,您可以執行上述相同的操作,即每個人將交易發送給下一個要簽名的人,而不是發回給您進行合併。
同樣,這個過程有點龐大,需要一個人知道正在使用的輸入的部分(或全部)資訊(私鑰除外)。但與原始事務方法相比,它導致錯誤的可能性略小。PSBT 還允許您使用其他支持 PSBT 的非比特幣核心錢包,您可以將此方法用於未連接到網際網路或沒有區塊鍊或交易中花費的 UTXO 的錢包。
但是,Bitcoin Core 0.18 實際上使整個過程變得容易得多。比特幣核心 0.18 引入了幾個新的
*psbt
RPC,使得一個人不需要知道所有正在使用的輸入以及每個輸入的所有資訊。唯一需要注意的是,這種方法假設每個人都有自己想要創建的輸出,而不是多個人將他們的比特幣集中在一起以產生一個大的輸出。在 0.18 中,每個人都可以使用
walletcreatefundedpsbt
. 他們指定他們想要使用的任何自己的輸入和所有輸出。將添加任何更改輸出,如果使用者指定的金額不足,將添加來自錢包的額外輸入以覆蓋輸出金額和交易費用。由於每個使用者都使用自己的錢包進行此操作,因此沒有人需要知道其他使用者錢包裡有什麼。然後每個人將 PSBT 發送給指定的協調員,該協調員用於
joinpsbts
將每個 PSBT 加入一個大型 PSBT。這個 PSBT 將擁有每個人想要花費和創造的所有輸入和輸出。因此,不再有許多單獨的 PSBT 具有自己的輸入和輸出,而是現在有一個具有每個人輸入和輸出的大型 PSBT。
walletprocesspsbt
然後將此 PSBT 發送回用於更新 PSBT 並將其輸入資訊添加到 PSBT 並簽名的每個人。即使使用者有一個氣隙設置,其中他們的私鑰位於無法訪問區塊鏈的地方,他們也可以從僅線上觀看的錢包中更新 PSBT,並將 PSBT 發送到離線機器進行簽名。一旦每個人都簽署了 PSBT,它就會被發送回協調者,協調者用來
combinepsbt
將所有簽名和輸入資訊組合到同一個 PSBT 中,然後使用 . 創建最終的網路交易finalizepsbt
並使用sendrawtransaction
.同樣,這可以像前面描述的其他方法一樣連續完成,因此不需要
combinepsbt
.