PSBT (BIP 174) - Partially Signed Bitcoin Transactions

Multisig transactions 1 have been a great use case of Bitcoin for the past few years, they require unsigned or partially signed transactions to be passed between multiple parties to “co-sign” them. However, there is currently no unified format for how multiple parties may share these transactions between multiple signers, it depends on the particular implementation for each wallet making it hard to do among parties using different Bitcoin wallets.

A draft BIP (174), which was proposed last year by Andrew Chow, was recently a subject of interest among Bitcoin developers. It aims to create a standard extensible format that different clients can implement making Partially Signed Bitcoin Transactions (PSBT) easier to pass around users to sign and combine their signatures.

Since signing transactions alsow requires signers to have access to the UTXOs being spent, this format also aims to allow offline signers such as hardware and “air-gappd” wallets to sign transactions without needing to access the UTXO set and witout being defrauded. To explain the need for this BIP, we’re going to start with an example of why this is important.

Say I’m Bob, I’d like to pay Alice 5 BTC in exchange for a service, but I don’t trust Alice and we both trust Mark, so we create a 2-of-3 Multisig address with 5 Bitcoins between Alice, Bob and Mark. Now Alice did not provide the service and I would like to get my money back, I’m going to create a PBST and send it to Mark. Mark, being an Escrow, cares about the security of his coins so he signs my PSBT transaction using an offline machine and sends it back to me, I’ll then take my signed transaction and Mark’s signed transaction, combine and serialize them then broadcast them to the network as a valid serialized network transaction that spends the inputs back to my address using 2 different signatures.

Another example would be the scenario where we are doing something like a group purchase, I can make a PSBT with my inputs, pass it around to different parties, each of them will in turn add their inputs and sign the transaction, then I’ll sign the transaction, finalize and serialize it then send it to the network.

Multisig Workflow using PSBTs

Multisig Workflow using PSBTs

The PSBT format consists of key-value pairs <key>|<value>, the keys are most of the time just a one byte hex integer, or a hex integer concatenated with a public key. They consist of “global types”, which apply to both inputs and outputs,“per-input” and “per-output” types. Currently the defined “per-input” and “per-output” types include: Witness Script, Redeem Script and BIP 32 derivation path, with extra types in the “per-input” field like Witness UTXO and Non-Witness UTXO, Sighash Type , Partial Signature, Finalized scriptSig and Finalized scriptWitness.

The transaction format will be as follows:

{0x70736274}|{0xff}|{global key-value map}|{input key-value map}|...|{input key-value map}
Name Type Value Description
Magic Bytes int32_t 0x70736274 This is a 4 byte integer that is the ASCII for PSBT
Separator Char 0xff This is always 0xff to fail any serialization attempt from a non-PSBT serializer
Global Data Key-value map Varies Key-value map for all global data
Inputs Array of key-value maps Varies These are the key-value pairs we mentioned earlier
Outputs Array of key-value maps Varies These are the key-value pairs we mentioned earlier

There has been discussions in the Bitcoin-dev recently against the key-value model, calling for a simpler set model, it’s argued that this can be better in human readability and have more space efficiency as some keys can be dropped, but this most likely won’t be implemented as it is a drastic change from the original BIP proposal.

As proposed by the current BIP, there are 4 different roles a party can play during the partial signing scheme, a Creator, Signer, Combiner and Input Finalizer. A new update to the BIP, currently still being discussed, adds an Updater and a Transaction Extractor roles.

  • The Creator creates an unsigned transaction and places it in a new PSBT, along with creating an empty input field.

  • The Updater accepts a PSBT and adds information to it, they add the UTXO, redeemScripts, witnessScripts and BIP 32 derivation paths if available.

  • The Signer doesn’t add any data sources, instead they create signatures for the transactions they can sign and add them as a “Partial Signature” key-value pair for the input it relates too, the Signer can also compute addresses, values being sent and transaction fees, showing them to the user as a confirmation and a warning.

  • The Combiner merges one or more PSBTs removing any duplicate key-value pairs, the Combiner does not need to understand how to interpret the script, it just combines them according to the specifications.

  • The Finalizer accepts only one PBST, it determines if the input has enough data to pass validation and if it does it constructs the scriptSig and scriptWitness and gets rid of all data except UTXO and unknown fields in the input key-value map.

  • The Transaction Extractor accepts a single PSBT and checks if all the inputs have complete scriptSigs and scriptWitnesses, if they do, the Extractor serializes the transactions and outputs a fully valid network transaction.

The format is designed to be extended in the future by adding new types for the key-value pairs, making it backward compatible as Signers that don’t identify the new codes will just ignore them. To ensure compatibility it also designed to not be “unserializable” by normal transaction unserializers.

Regarding the encoding of a PSBT, it can either be represented by a Base64 string or a plain binary file with the .psbt file extension. A MIME type name will be added once the BIP has been revised.

This new format can bring a whole new adoption level to Multisig wallets, the BIP is still currently listed as a Draft but we should seeing it promoted to Proposed soon and maybe start seeing implementations pop up once in a while!

Comments powered by Talkyard.