PSBT is short for Partially Signed Bitcoin Transaction. It is a standard for defining transactions that can be signed by multiple signers across different clients. It contains the necessary information for a signer to produce a signature for a transaction. This is specifically beneficial for offline signers as they cannot fetch additional information about a transaction. The original PSBT format was specified in BIP 174 and a Version 2 in progress in BIP 370.
The PSBT Binary format
The PSBT format consists of key-value maps separated by a 0x00
byte. It supports the following maps:
- The Global Map contains key-value pairs that apply to the entire transaction
- The Input Map contains key-value pairs that apply to individual inputs
- The Output Map contains key-value pairs that apply to individual outputs
Key-value pairs in each map all follow this format:
<keylen> <keytype> <keydata> <valuelen> <valuedata>
The keylen
, keytype
and valuelen
are specified as a compact size unsigned integer which ensures values that can be specified in one byte will be specified in one byte, for example, the decimal number ten is specified as 0x0a
instead of 0x000a
.
keydata
is not always available. Some key types like PSBT_GLOBAL_UNSIGNED_TX = 0x00
do not have keydata
.
To see the full list of key types supported, go to BIP 174.
Let's look at a few examples:
We'll start by breaking down this PSBT which is an unsigned tx with 0 inputs and 0 outputs.
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
Let's breakdown another simple unsigned PSBT data with 1 input and 1 output
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
Signing a PSBT
The Signer uses the UTXOs provided in the PSBT to produce signatures for inputs. The signer performs some checks before signing.
- For non-witness inputs, the signer verifies that the
txid
of the non-witness utxo matches thetxid
specified in the unsigned transaction. - For witness-inputs, the signer verifies that the
witnessScript
(if provided) matches the hash specified in the UTXO or theredeemScript
, and theredeemScript
(if provided) matches the hash in the UTXO
Any signatures created by the Signer must be added as a PSBT_IN_PARTIAL_SIG = 0x02
key-value pair for the respective input it relates to. If a Signer cannot sign a transaction, it must not add a Partial Signature.
Our previous PSBT spends from a non-witness utxo. Before we sign it, we must add the PSBT_IN_NON_WITNESS_UTXO = 0x00
key-value pair for that input:
0100b6020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402bd0300ffffffff02c817a804000000002321035b4a568361af71783c22a6c9d9a13e3d5f32d9a7278c0e8325e4bc29b0090825ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9012000000000000000000000000000000000000000000000000000000000000000000000000000
The global map is unchanged but new data has been added to the input map:
<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
To sign, we add the following PSBT_IN_PARTIAL_SIG = 0x02
key-value pair to the input pair:
<keylen> 0x22 //
<keytype> 0x02 // PSBT_IN_PARTIAL_SIG keytype
<keydata> 0x035b4a568361af71783c22a6c9d9a13e3d5f32d9a7278c0e8325e4bc29b0090825
<valuelen> 0x47
<valuedata>
3044022063179cb0f91d2b1d2c45d8112a527e4491ec771befb62c5717afac69f42345d9022035b3c00d8cb2f6309e0c0f6df03f54ae3e0bd6c4cae68061a714b57cf4f8cd8c01
Finalizing a PSBT
The Finalizer validates each input, removes the partial sigs and constructs the PSBT_IN_FINAL_SCRIPTSIG = 0x07
and PSBT_IN_FINAL_SCRIPTWITNESS = 0x08
for each input and places them in the Input Map.
Our finalized PSBT looks like this:
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
Extracting a serialized transaction
The Extractor uses the unsigned transactions and signatures provided in the PSBT to construct a serialized transaction.
Conclusion
The PSBT standard is a key innovation in the world of Bitcoin transactions. We have only scratched its surface, if you want to read the full specification, go to BIP 174.
Top comments (0)