PSBT对于部分签名的比特币事务而言是短的。它是定义交易的标准,可以由多个签名人跨不同客户签署。它包含签名者为交易产生签名的必要信息。这对离线签名者特别有益,因为它们无法获取有关交易的其他信息。原始的PSBT格式在BIP 174中指定,BIP 370中正在进行的版本2。
PSBT二进制格式
PSBT格式由由0x00
字节隔开的键值图组成。它支持以下地图:
- 全局地图包含适用于整个交易的键值对
- 输入地图包含适用于单个输入的键值对
- 输出图包含适用于单个输出的键值对
每个地图中的键值对均遵循此格式:
<keylen> <keytype> <keydata> <valuelen> <valuedata>
keylen
,keytype
和valuelen
被指定为compact size unsigned integer,可确保可以在一个字节中指定可以在一个字节中指定的值,例如,小数号为十进制数字为0x0a
而不是0x0a
,而不是0x000a
。
keydata
并不总是可用。 PSBT_GLOBAL_UNSIGNED_TX = 0x00
之类的一些关键类型没有keydata
。
要查看支持的密钥类型的完整列表,请转到BIP 174。
让我们看一些示例:
我们将首先分解此PSBT,该PSBT是一个未签名的TX,具有0个输入和0输出。
70736274ff01000a0000000000000000000000
<magic> 0x70736274ff // used to identify PSBT data
<global-map> // contains global transaction data
<keylen> 0x01 // Key length is one byte
<keytype> 0x00 // PSBT_GLOBAL_UNSIGNED_TX
<valuelen> 0x0a // 10 bytes
<valuedata> 0x00000000000000000000 // The Tx hex
<separator> 0x00
让我们分解另一个带有1个输入和1个输出的简单无符号的PSBT数据
0x70736274ff0100550200000001eb63366191dbaf74d30c6de8cbb7208de3fb65ad266b41c56990a5a7e6a2eac90000000000ffffffff010017a804000000001976a914c1752bf5bffbd320ab2ab625b32b9fe48337dce488ac00000000000000
<magic> 0x70736274ff
<global-map>
<keylen> 0x01 // Key length is one byte
<keytype> 0x00 // PSBT_GLOBAL_UNSIGNED_TX
<valuelen> 0x55 // 85 bytes
<valuedata> 0x0200000001eb63366191dbaf74d30c6de8cbb7208de3fb65ad266b41c56990a5a7e6a2eac90000000000ffffffff010017a804000000001976a914c1752bf5bffbd320ab2ab625b32b9fe48337dce488ac00000000 // The Unsigned Tx hex
<separator> 0x00
<input-map>
<separator> 0x00
<output-map>
<separator> 0x00
签署PSBT
签名者使用PSBT中提供的UTXO来产生输入的签名。签名者在签名之前执行一些检查。
- 对于非授权输入,签名者验证了非授权UTXO的
txid
是否与未签名的事务中指定的txid
匹配。 - 对于证人输入,签名者验证了
witnessScript
(如果提供)与UTXO或redeemScript
中指定的哈希匹配,而redeemScript
(如果提供)(如果提供)与UTXO 中的哈希匹配。
必须将签名者创建的任何签名添加为其与之相关的相应输入的PSBT_IN_PARTIAL_SIG = 0x02
键值对。如果签名者无法签署交易,则不得添加部分签名。
我们以前的PSBT从非授权UTXO上花费。在签名之前,我们必须为该输入添加PSBT_IN_NON_WITNESS_UTXO = 0x00
键值对:
0100b6020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402bd0300ffffffff02c817a804000000002321035b4a568361af71783c22a6c9d9a13e3d5f32d9a7278c0e8325e4bc29b0090825ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000000000000
全局地图没有变化,但已将新数据添加到输入地图:
<input map>
<keylen> 0x01 // 1 byte
<keytype> 0x00 // PSBT_IN_NON_WITNESS_UTXO, requires no keydata
<valuelen> 0xb6 // 182 bytes
<valuedata> // the transaction in network serialization format the current input spends from
0x020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402bd0300ffffffff02c817a804000000002321035b4a568361af71783c22a6c9d9a13e3d5f32d9a7278c0e8325e4bc29b0090825ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000
<separator> 0x00
要签名,我们将以下PSBT_IN_PARTIAL_SIG = 0x02
键值对添加到输入对:
<keylen> 0x22 //
<keytype> 0x02 // PSBT_IN_PARTIAL_SIG keytype
<keydata> 0x035b4a568361af71783c22a6c9d9a13e3d5f32d9a7278c0e8325e4bc29b0090825
<valuelen> 0x47
<valuedata>
3044022063179cb0f91d2b1d2c45d8112a527e4491ec771befb62c5717afac69f42345d9022035b3c00d8cb2f6309e0c0f6df03f54ae3e0bd6c4cae68061a714b57cf4f8cd8c01
最终确定PSBT
最终器验证了每个输入,删除部分信号并为每个输入构造PSBT_IN_FINAL_SCRIPTSIG = 0x07
和PSBT_IN_FINAL_SCRIPTWITNESS = 0x08
,然后将它们放在输入映射中。
我们最终确定的PSBT看起来像这样:
0x70736274ff0100550200000001eb63366191dbaf74d30c6de8cbb7208de3fb65ad266b41c56990a5a7e6a2eac90000000000ffffffff010017a804000000001976a914c1752bf5bffbd320ab2ab625b32b9fe48337dce488ac0000000000
// Global map is unchanged
0100b6020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402bd0300ffffffff02c817a804000000002321035b4a568361af71783c22a6c9d9a13e3d5f32d9a7278c0e8325e4bc29b0090825ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000
// PSBT_IN_NON_WITNESS_UTXO is unchanged
// PSBT_IN_PARTIAL_SIG has been removed
<keylen> 0x01
<keyvalue> 0x07 // PSBT_IN_FINAL_SCRIPT_SIG
<valuelen> 0x48
<value> 0x473044022063179cb0f91d2b1d2c45d8112a527e4491ec771befb62c5717afac69f42345d9022035b3c00d8cb2f6309e0c0f6df03f54ae3e0bd6c4cae68061a714b57cf4f8cd8c01
0000
提取串行交易
提取器使用PSBT中提供的未符号交易和标志来构建串行交易。
结论
PSBT标准是比特币交易界的关键创新。如果您想阅读完整的规范,我们只抓取它的表面,请转到BIP 174。