PSBT标准
#node #web3 #bitcoinjs #bitcoin

PSBT对于部分签名的比特币事务而言是短的。它是定义交易的标准,可以由多个签名人跨不同客户签署。它包含签名者为交易产生签名的必要信息。这对离线签名者特别有益,因为它们无法获取有关交易的其他信息。原始的PSBT格式在BIP 174中指定,BIP 370中正在进行的版本2。

PSBT二进制格式

PSBT格式由由0x00字节隔开的键值图组成。它支持以下地图:

  • 全局地图包含适用于整个交易的键值对
  • 输入地图包含适用于单个输入的键值对
  • 输出图包含适用于单个输出的键值对

每个地图中的键值对均遵循此格式:

<keylen> <keytype> <keydata> <valuelen> <valuedata>

keylenkeytypevaluelen被指定为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 = 0x07PSBT_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