Skip to content
DonateБГ

Transactions

PSBT

A PSBT, or partially signed Bitcoin transaction, carries an unsigned transaction and its signing data between wallets. Learn its BIP 174 format.

By Dimitar Zurnov · Updated 4 Nov 2026
Adapted from Learn Me a Bitcoin by Greg Walker.

A PSBT, or partially signed Bitcoin transaction, packages an unsigned transaction with the extra information each signer needs to sign it. Wallets and devices pass PSBTs back and forth until every input has its signatures. The format is defined in BIP 174, with a second version in BIP 370. A PSBT never contains a private key.

Why does a signer need more than the transaction?

An unsigned transaction holds the inputs and outputs, but not everything a signature depends on. To sign a SegWit input, a signer needs the amount and the locking script of the output being spent. Those details live in the earlier transaction that created the output, not in the transaction that spends it.

A wallet connected to the internet can fetch them. An offline signer, such as a hardware device or a cold wallet, cannot. For SegWit inputs the amount is part of what the signature covers, so a signer that cannot see it cannot sign correctly.

A PSBT solves this by carrying the missing details with the transaction. That lets an offline device sign, and it lets two wallets from different software work on the same transaction.

What is inside a PSBT?

A PSBT is a sequence of key-value pairs, grouped into maps. It can be stored as a binary file or encoded as base64 text, and both forms hold the same data.

A PSBT is a header followed by a global map, one input map per input and one output map per output, each map ending in a zero byte. header: psbt, then ff 70736274ff global map: one, holds the transaction ends with a 00 byte input maps: one for each input each ends with a 00 byte output maps: one for each output each ends with a 00 byte each entry: key length, key type, key data, value length, value
The maps come in a fixed order, and each one ends with a zero byte.

The structure has four parts, in this order:

  1. Header. The five bytes 70736274ff: the ASCII letters psbt, then a separator byte ff.
  2. Global map. Exactly one. It holds information about the whole transaction.
  3. Input maps. One for each input in the transaction, in the same order.
  4. Output maps. One for each output, in the same order.

A map is a list of entries, and it ends with a single 00 byte. A map with nothing to say is just that 00 byte.

Each entry has four fields:

Field Size Meaning
Key length compact size the size of the key type and key data that follow
Key type 1 byte, usually which kind of data this entry holds
Key data optional extra information, such as a public key, that makes the key unique
Value length compact size the size of the value
Value variable the data itself

Key lengths and value lengths use compact size numbers, so short fields take one byte. A key type is a number, and the same number can mean different things in different maps. Key type 0x00 in the global map is the unsigned transaction, while key type 0x00 in an input map is the previous transaction.

What does a real PSBT contain?

The BIP 174 test vectors include a valid PSBT with one P2PKH input, and both of its output maps are empty. Its first bytes show the structure in practice. The diagram below walks through them:

The first bytes of a valid BIP 174 test PSBT: the header, the global map holding a 117-byte transaction, and empty maps after it. magic bytes and separator 70736274ff global map: the unsigned transaction 01 00 75: key 00, length 117 117 bytes: version 2, 1 input, 2 outputs end of global map 00 input map: the previous transaction 01 00 fd a5 01: key 00, length 421 421 bytes, and its txid matches the input end of input map 00 two output maps, both empty 00 00
The first valid test vector in BIP 174, decoded by hand and checked in code.
  • Global map. Key 00 holds the unsigned transaction, which is 117 bytes. It has version 2, one input and two outputs, of 99,999,699 and 100,000,000 satoshis. The inputs have empty unlocking scripts, because nothing is signed yet.
  • Input map. Key 00 holds the full previous transaction, which is 421 bytes. Its ID matches the outpoint the input spends, so a signer can check the amount it is about to sign for.
  • Output maps. Two maps, both empty, so each contains only the 00 terminator.

The test vector is a good example to decode yourself. Its base64 form begins cHNidP8, because that is the base64 encoding of the header bytes. Every PSBT in base64 starts that way.

How do PSBTs move between parties?

A PSBT passes through several roles. Each role adds one kind of information, and a single device or wallet often plays more than one.

The PSBT roles run in order: Creator, Updater, Signer, Input Finalizer and Extractor; a Combiner can merge copies signed in parallel. Creator: builds the unsigned transaction Updater: adds the data each signer needs Signer: adds signatures, often offline Input Finalizer: builds the unlocking data Extractor: outputs the signed transaction Combiner: merges copies signed in parallel
Roles can be split across devices, or combined in one wallet.
  • Creator. Builds the unsigned transaction and starts the PSBT.
  • Constructor. Adds inputs and outputs before signing. This role exists only in version 2.
  • Updater. Adds the data a signer needs, such as the previous transaction, the scripts and the key paths.
  • Signer. Checks the transaction and adds its partial signatures. This is the step a hardware device performs, usually offline.
  • Input Finalizer. Turns the partial signatures into the final unlocking data for each input.
  • Extractor. Builds the finished transaction from the finalized inputs, ready to broadcast.
  • Combiner. Merges copies of the same PSBT that different parties have signed in parallel.

A signer should always check the outputs, amounts and fee before it signs, because the PSBT is only as trustworthy as the wallet that made it.

Using Bitcoin Core

Bitcoin Core has RPC commands for each role. The PSBT guide in its repository lists them:

  • walletcreatefundedpsbt creates a PSBT, adds inputs and change, and fills in the data it knows.
  • walletprocesspsbt fills in more data and signs the inputs its keys can sign.
  • combinepsbt merges copies that different signers have processed.
  • finalizepsbt finalizes the inputs and, if all are complete, returns the signed transaction.
  • decodepsbt prints a PSBT in readable form, which is useful for checking one before you sign it.

Bitcoin Core 32.0 and later read and create version 2 PSBTs. Its createpsbt, walletcreatefundedpsbt, converttopsbt and psbtbumpfee RPCs create version 2 by default, and their psbt_version argument picks another version. Releases before 32.0 reject version 2 PSBTs.

Which key types exist?

Every entry has a key type. BIP 174 defines the version 0 types below.

Map Type Name Holds
Global 0x00 Unsigned transaction the transaction, with empty scripts
Global 0x01 Extended public key an xpub and its derivation path
Global 0xFB Version the PSBT version number
Input 0x00 Non-witness UTXO the full previous transaction
Input 0x01 Witness UTXO the amount and script of the output spent
Input 0x02 Partial signature a signature and the public key it belongs to
Input 0x03 Sighash type the signature hash type the signer must use
Input 0x04 Redeem script the script behind a P2SH lock
Input 0x05 Witness script the script behind a P2WSH lock
Input 0x06 BIP 32 derivation the key path, so a device knows which key to use
Input 0x07 Final scriptSig the finished unlocking script
Input 0x08 Final scriptWitness the finished witness
Output 0x00 Redeem script the script behind a P2SH output
Output 0x01 Witness script the script behind a P2WSH output
Output 0x02 BIP 32 derivation the key path of the output's key, often a change output

A simple wallet only needs a handful of these. For a P2PKH input, the unsigned transaction, the previous transaction, partial signatures and the final scriptSig are enough. The derivation paths are optional, but they help a device recognize its own outputs.

Version 0 also has input types 0x0a to 0x0d, which carry the preimages of hashes for scripts that check a hash. Type 0xFC in any map holds proprietary data that a wallet defines for itself.

What changed in version 2?

Version 0 stores the whole unsigned transaction in the global map. That makes it hard to add or remove inputs and outputs after the PSBT is made, because the whole transaction would have to be rebuilt.

BIP 370 defines version 2. It splits the transaction into separate fields, so each part can change on its own. Version 2 is marked by the global key 0xFB with the value 2, and it adds these keys:

Scope Type Name Holds
Global 0x02 Transaction version the transaction version number
Global 0x03 Fallback locktime the locktime used when no input sets one
Global 0x04 Input count how many inputs the transaction has
Global 0x05 Output count how many outputs the transaction has
Global 0x06 Transaction modifiable whether inputs or outputs may still be added
Input 0x0e Previous TXID the transaction holding the output being spent
Input 0x0f Output index which output of that transaction is spent
Input 0x10 Sequence the sequence number for the input
Input 0x11 Required time locktime a time the transaction must wait for
Input 0x12 Required height locktime a height the transaction must wait for
Output 0x03 Amount the value of the output
Output 0x04 Script the locking script of the output

Version 2 also adds the Constructor role, which lets a party add inputs and outputs before anyone signs. The transaction's locktime is worked out from the inputs' required locktimes, or from the fallback locktime when no input sets one. The two versions are not compatible, so a parser must read the version first.

Version 1 is skipped. People already called the original format version 1, so BIP 370 numbers the new one 2 to avoid confusion.

How do you keep a PSBT safe?

A PSBT does not contain private keys, but it does reveal a lot. It can include extended public keys and derivation paths, which let anyone who has them see every address derived from them. Share a PSBT only with the parties who need it.

Before you sign, check three things on the signing device itself: the destination of each output, the amount, and the fee. The device is the last point where a mistake can be caught, because the signature is final once it is made. The fee page explains how to work out the fee from the inputs and outputs.

How did PSBTs begin?

Pieter Wuille suggested a standard format for unsigned transactions, and Ava Chow designed the format and wrote BIP 174. BIP 174 was assigned in 2017, and Bitcoin Core added PSBT RPCs in version 0.17. BIP 370 was assigned in 2021 and added version 2.

For a broader look at how PSBTs are used, Bitcoin Optech's PSBT topic collects the common workflows and the tools that support them. The input and output pages explain the fields a PSBT carries for each. The next section, Script, covers the locks that outputs carry.

Sources

In this section: Transactions

All of Bitcoin from zero

Something look wrong? Tell us