Glossary / Developer reference
Pubkey script
Also known as scriptPubKey, Locking script.
- Definition
- The pubkey script is the short piece of Bitcoin Script attached to every transaction output, stating the conditions that must be met before the coins in that output can move again.
Bitcoins are not held in an address; they sit in outputs, each guarded by a pubkey script. Bitcoin Core calls the field scriptPubKey, and for an ordinary modern output it is 22 or 34 bytes long. When you give someone an address, you are handing them the recipe for the pubkey script their wallet will write.
How it works
Each output in a serialized transaction is three things in a row: eight bytes of value in satoshis, a length prefix, and the pubkey script itself. Nothing in the output names a recipient. The script is the recipient, and an address is only a checksummed encoding of the handful of bytes inside it.
Five templates account for almost everything on the chain today. A legacy pay-to-public-key-hash lock runs 25 bytes and names four opcodes around a 20-byte hash. A pay-to-script-hash lock is 23 bytes and ends with OP_EQUAL. Native SegWit is deliberately dumb by comparison: a version byte followed by a single push, 22 bytes for a single key and 34 bytes for a script hash, with no logic in the output at all. Taproot is also 34 bytes, a version byte and a 32-byte key.
Relay policy recognises that short list and refuses to pass anything else along, which is why you cannot invent your own output format and expect a wallet to pay it. Consensus is looser than policy here, but the practical effect is that the five templates are the whole menu.
The name is a fossil. In the earliest transactions the script really did contain a public key: the coinbase output of the genesis block is 67 bytes holding an uncompressed 65-byte key followed by OP_CHECKSIG, and you can read it in the source of Bitcoin Core itself. Paying a hash instead of a key became the norm during 2011, and today most pubkey scripts contain no public key whatsoever, only a commitment to one.
Where you see it
Ask any node to decode a raw transaction and every output carries a scriptPubKey object with four fields: the human-readable assembly, the raw hex, the type string, and the address the type maps to. Block explorers show the same thing, usually relabelled as the locking script or the output script.
It is also where a wallet's watch-only setup lives. Importing an address means telling your software which pubkey scripts to scan the chain for, which is why a descriptor, a definition that generates the whole family of scripts a key can produce, has replaced address-by-address importing in serious tooling.
The practical reading skill is short. If the script starts with a 0 and holds 20 bytes, someone will spend it with one signature and a cheap input. If it holds 32 bytes, there is a contract behind it that you cannot see. If it starts with 1 and holds 32 bytes, it is Taproot and it may be a single key or an entire tree of conditions wearing the same face.
Pubkey script vs Signature script
The pubkey script sets the question and the signature script tries to answer it, and they are written by different people at different times. Whoever sends you money writes the pubkey script, from the address you gave them, and pays for its bytes. You write the signature script later, when you spend, and pay for those bytes yourself. That is why sending to a Taproot address costs the sender slightly more than sending to a legacy one while saving you considerably more when you eventually move the coins. The two scripts also run separately rather than as one joined program, a change made in 2010 after the original combined execution turned out to be exploitable.