Skip to content
buybitcoinsmart

Glossary / Developer reference

PP script

Definition
PP script was the required field in a BIP70 output holding the raw locking script the payer had to reproduce, the same bytes that end up in a transaction output.

Specified in BIP-70.

Of everything BIP70 put on the wire, the script is the only part that survived onto the blockchain. Certificates, notes and expiry times all stayed off-chain, while the locking script went into the transaction verbatim and sits today in the set of unspent outputs. Those bytes, and nothing else in the request, decide who can spend the coins.

How it works

Status: historical. The script was field 2 of the Output message and the one part of it a merchant could not omit, since the amount defaulted to zero. Bitcoin Core stopped parsing any of it in 0.20.0, released June 3, 2020.

Sending a script instead of an address was a deliberate choice. An address is a human transport format: base58check or bech32, with a prefix, a checksum and a character set chosen to survive being written down and read aloud. A wallet that receives one has to decode it into a script before it can build anything. BIP70 skipped the round trip and named the destination in the form the network actually uses.

The standard forms have fixed sizes, and knowing them makes a block explorer far easier to read:

  • Pay to public key hash, 25 bytes: duplicate, hash, push 20 bytes, verify equality, check signature.
  • Pay to script hash, 23 bytes: hash, push 20 bytes, check equality.
  • Single-key segwit, 22 bytes: a zero version byte and a 20-byte hash.
  • Script-hash segwit, 34 bytes: version zero and a 32-byte hash.
  • Taproot, 34 bytes: version one and a 32-byte key.

What the format gave up was error detection. Bech32 guarantees that any four substituted characters in an address of up to 89 characters are caught, and base58check catches corruption with a four-byte hash. Raw script bytes carry neither. A flipped bit in an address produces a string your wallet rejects; a flipped bit in a script produces a valid output that nobody can ever spend.

Where you see it

Script types are the reason two withdrawals of the same size can cost different fees.

An exchange that lets you pick an address format is picking a script for you. A single-key segwit output takes 22 bytes against 25 for the legacy form, which is trivial, but spending it later is not: that input costs roughly 68 virtual bytes where a legacy one costs about 148, so coins you receive today set part of your fee bill for the rest of their life. At 20 sat/vB the gap is about 1,600 satoshis for every input you eventually spend.

Explorers name the type of each output they display, which is how you can check what you were actually paid into. Newer software describes destinations with output descriptors, a compact text form covering a whole family of scripts and their derivation rather than one script at a time.

The habit worth keeping from all of this is simple. Confirm the destination on a device with its own screen, because malware that swaps an address in your clipboard is common and a hardware wallet displaying the real recipient is the check that catches it.

PP script vs pubkey script

The BIP70 field was a container; a pubkey script is the thing itself. A pubkey script, also called the scriptPubKey or the locking script, appears in every transaction output ever created and states the condition a spender must satisfy. PP script was one particular place a copy of one traveled, inside a protocol nobody runs. Use the field name only when reading BIP70 documentation, and the general name everywhere else.

Not to be confused with

Frequently asked questions

Why did BIP70 send a script instead of a bitcoin address?

Because the script is what a transaction actually contains. An address is an encoding of the same destination with a checksum wrapped around it, so sending the script removed a decoding step, at the cost of losing the checksum that catches typos.

Does the address format you withdraw to change your fees?

Yes, mostly when you later spend the coins. A single-key segwit input costs around 68 virtual bytes against roughly 148 for a legacy one, so at 20 sat/vB you save about 1,600 satoshis per input.

Read next

Related terms

More in Developer reference