ScriptPubKey

Locking code

Diagram showing the ScriptPubKey as the lock on an output in a bitcoin transaction.

The ScriptPubKey is the locking code for an output.

It's made up of Script, which is a mini programming language that allows you to place different types of locks on your outputs.

Most ScriptPubKeys use one of a standard set of locks, most commonly where the output is locked to a public key (e.g. P2PKH or P2WPKH).

ScriptPubKeys are usually encoded in to addresses to make them easier to pass around.

Examples

What does a ScriptPubKey look like?

Here are some examples of ScriptPubKeys you'll find on outputs in the blockchain.

P2PK

Legacy

OP_PUSHBYTES_65
0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3
OP_CHECKSIG
410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac

Transaction: 0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9 (Output 0)

This is one of the simplest locking scripts you'll find in the blockchain. It's used to lock an output to a single public key.

It contains a public key (33 bytes compressed or 65 bytes uncompressed) and the OP_CHECKSIG opcode. This means that only a signature for that public key is required to unlock it. So in other words, the output is locked to the public key of the person you want to "send" the bitcoins to.

Although simple, these kinds of locking scripts are most commonly found on the outputs of coinbase transactions early on in the blockchain (e.g. genesis block transaction). This is because locking an output to a public key is most commonly done through the use of P2PKH instead…

P2PKH

Legacy

OP_DUP
OP_HASH160
OP_PUSHBYTES_20
55ae51684c43435da751ac8d2173b2652eb64105
OP_EQUALVERIFY
OP_CHECKSIG
76a91455ae51684c43435da751ac8d2173b2652eb6410588ac

Transaction: 0b6461de422c46a221db99608fcbe0326e4f2325ebf2a47c9faf660ed61ee6a4 (Output 1)

This is a very common locking script. It's also used to lock an output to a single public key.

However, instead of putting a raw public key directly in the locking script like in a P2PK, you put the public key hash (the HASH160 of a public key) in the locking script instead.

Public Key
HASH160

So when you come to unlock this output, you need to provide a signature and the original public key. So now the P2PKH unlocking script first checks that the original public key matches the public key hash, and then proceeds to check the signature against the public key as normal.

The reason why P2PKH is preferred over P2PK is because Satoshi thought that it would shorten the locking script by putting the hash of a public key inside it (20 bytes) rather than the full uncompressed public key (65 bytes). The P2PKH script was then given its own address format, and therefore became the easiest and most prevalent method for transferring ownership of coins.

P2MS

Legacy

OP_2
OP_PUSHBYTES_65
04d81fd577272bbe73308c93009eec5dc9fc319fc1ee2e7066e17220a5d47a18314578be2faea34b9f1f8ca078f8621acd4bc22897b03daa422b9bf56646b342a2
OP_PUSHBYTES_65
04ec3afff0b2b66e8152e9018fe3be3fc92b30bf886b3487a525997d00fd9da2d012dce5d5275854adc3106572a5d1e12d4211b228429f5a7b2f7ba92eb0475bb1
OP_PUSHBYTES_65
04b49b496684b02855bc32f5daefa2e2e406db4418f3b86bca5195600951c7d918cdbe5e6d3736ec2abf2dd7610995c3086976b2c0c7b4e459d10b34a316d5a5e7
OP_3
OP_CHECKMULTISIG
524104d81fd577272bbe73308c93009eec5dc9fc319fc1ee2e7066e17220a5d47a18314578be2faea34b9f1f8ca078f8621acd4bc22897b03daa422b9bf56646b342a24104ec3afff0b2b66e8152e9018fe3be3fc92b30bf886b3487a525997d00fd9da2d012dce5d5275854adc3106572a5d1e12d4211b228429f5a7b2f7ba92eb0475bb14104b49b496684b02855bc32f5daefa2e2e406db4418f3b86bca5195600951c7d918cdbe5e6d3736ec2abf2dd7610995c3086976b2c0c7b4e459d10b34a316d5a5e753ae

Transaction: 581d30e2a73a2db683ac2f15d53590bd0cd72de52555c2722d9d6a78e9fea510 (Output 0)

This locking script allows you to lock an output to multiple public keys.

To unlock a P2MS you need to provide the required number of signatures. The first opcode (e.g. OP_2) indicates how many signatures are required, and the second-to-last opcode (e.g. OP_3) indicates how many public keys are in the locking script. So in this example, you need to provide a signature for any 2 of the 3 public keys.

However, these "raw" P2MS scripts are quite rare, as these kinds of large and complex script typically get wrapped up in the more efficient P2SH instead…

P2SH

Legacy

OP_HASH160
OP_PUSHBYTES_20
748284390f9e263a4b766a75d0633c50426eb875
OP_EQUAL
a914748284390f9e263a4b766a75d0633c50426eb87587

Transaction: 450c309b70fb3f71b63b10ce60af17499bd21b1db39aa47b19bf22166ee67144 (Output 1)

This is a special type of script that was introduced in 2012 (BIP 16). It allows you to lock an output using a custom locking script.

Similar to a P2PKH, a P2SH contains a hash, but instead of a public key hash it contains a script hash (the HASH160 of a script).

For example, in the example above, the 748284390f9e263a4b766a75d0633c50426eb875 is the hash of the following P2MS script:

Redeem Script
OP_1 
OP_PUSHBYTES_33 
022afc20bf379bc96a2f4e9e63ffceb8652b2b6a097f63fbee6ecec2a49a48010e 
OP_PUSHBYTES_33 
03a767c7221e9f15f870f1ad9311f5ab937d79fcaeee15bb2c722bca515581b4c0 
OP_2 
OP_CHECKMULTISIG
5121022afc20bf379bc96a2f4e9e63ffceb8652b2b6a097f63fbee6ecec2a49a48010e2103a767c7221e9f15f870f1ad9311f5ab937d79fcaeee15bb2c722bca515581b4c052ae
Script
HASH160

So when you come to unlock a P2SH, you need to provide the original locking script (Redeem Script) along with the unlocking script code. So in other words, the ScriptPubKey contains the hash of a locking script, and the ScriptSig contains the complete locking and unlocking script.

OP_RETURN

OP_RETURN 
OP_PUSHBYTES_11 
68656c6c6f20776f726c64
6a0b68656c6c6f20776f726c64

Transaction: 6dfb16dd580698242bcfd8e433d557ed8c642272a368894de27292a8844a4e75 (Output 2)

This ScriptPubKey is unspendable, but it allows you to store small amounts of data.

All you need to do is use the OP_RETURN opcode, followed by a data push of up to 80 bytes of any data of your choice.

It's most commonly used to store ASCII strings in the form of hex bytes. In the example above, the bytes 68656c6c6f20776f726c64 contain the ASCII-encoded string "hello world".

ASCII

P2WPKH

OP_0
OP_PUSHBYTES_20
853ec3166860371ee67b7754ff85e13d7a0d6698
0014853ec3166860371ee67b7754ff85e13d7a0d6698

Transaction: 39cc1562b197182429bc1ea312c9e30f1257be6d5159fcd7b375139d3c3fe63c (Output 0)

This locking script is used to lock an output to a single public key

It works in the same way as a P2PKH. However, whereas a P2PKH is unlocked using the ScriptSig field, a P2WPKH can only be unlocked through the Witness.

So just like a P2PKH, the P2WPKH locking script just contains a public key hash.

Public Key
HASH160

The benefit of using P2WPKH over P2PKH is that the P2WPKH uses the witness for unlocking, which gives a discount to the size of the unlocking code in terms of weight. This reduces the size of the transaction fee you need to use when spending a P2WPKH compared to a P2PKH.

You'll notice that a P2WPKH isn't using traditional Script opcodes. Instead, it just uses a fixed pattern, where any ScriptPubKey that starts with OP_O followed by the push of a 20-byte public key hash is interpreted as a P2WPKH locking script.

P2WSH

OP_0
OP_PUSHBYTES_32
65f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3
002065f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3

Transaction: 46ebe264b0115a439732554b2b390b11b332b5b5692958b1754aa0ee57b64265 (Output 1)

This locking script allows you to lock an output using a custom locking script.

It works in the same way as a standard P2SH. However, whereas a P2SH is unlocked using the ScriptSig field, a P2WSH can only be unlocked through the Witness.

And just like a P2SH, the P2WSH just contains a script hash (the hash of a "Witness Script"). However, instead of being the HASH160 of a script like in P2SH, a P2WSH contains the single SHA-256 of a script.

In the example above, the 65f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3 is the SHA-256 hash of the following P2MS script:

Witness Script
OP_2 
OP_PUSHBYTES_33 
03848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c 
OP_PUSHBYTES_33 
03cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b75 
OP_PUSHBYTES_33 
03eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e 
OP_3 
OP_CHECKMULTISIG
522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae
Script
SHA-256

The benefit of using P2WSH over P2SH is that the P2WSH uses the witness for unlocking, which gives a discount to the size of the unlocking code in terms of weight.

Once again, a P2WSH doesn't use any traditional Script opcodes. Any ScriptPubKey that starts with OP_O followed by the push of a 32-byte script hash is interpreted as a P2WSH locking script.

P2TR

OP_1
OP_PUSHBYTES_32
f3778defe5173a9bf7169575116224f961c03c725c0e98b8da8f15df29194b80
5120f3778defe5173a9bf7169575116224f961c03c725c0e98b8da8f15df29194b80

Transaction: d1c40446c65456a9b11a9dddede31ee34b8d3df83788d98f690225d2958bfe3c (Output 0)

This locking script behaves like a hybrid of the P2WPKH and P2WSH locking scripts.

This locking script locks an output to a tweaked public key. This tweaked public key is created from a normal public key, but it also includes a commitment to multiple optional custom scripts.

You are then able to unlock the output via the original public key, or by using one of the optional custom scripts.

P2TR locking scripts are unlocked via the Witness field.

The tweaked public key is 32 bytes (as opposed to 33 bytes like a compressed public key). This is because public keys in P2TR locking scripts do not include a leading byte to indicate the parity of the y-coordinate.

Custom

OP_2DUP
OP_ADD
OP_8
OP_EQUALVERIFY
OP_SUB
OP_2
OP_EQUAL
6e935888945287

Transaction: ab149362ea4e119d2bc5211b35083c23ec41842af6bbc2ff3c5f1e55941199cc (Output 0)

This is a custom locking script that uses opcodes to create a simple math problem that asks for two numbers that add to 8, and where the second number is 2 less than the first. This custom script was unlocked by providing the numbers OP_5 and OP_3.

So as you can see, the ScriptPubKey isn't restricted to simply locking to public keys; it can be used to create many different kinds of locks. However, it's quite rare to see these custom locking scripts appearing directly in the ScriptPubKey like this, as they're typically wrapped within a P2SH or P2WSH instead.

These kinds of custom locking scripts are considered non-standard. So whilst it's possible for them to be mined into the blockchain, they will not be relayed by nodes. So if you want to use a custom locking script like this, you would either need to mine it yourself, or wrap it inside a P2SH or P2WSH instead.

Terminology

What is it called a ScriptPubKey?

It's called a ScriptPubKey because it contains Script, and it usually locks an output to someone's public key.

But "ScriptPubKey" is a bit of a misnomer, because you're not limited to locking an output to a public key only. Nonetheless, locking to someone else's public key is the most common way of locking up bitcoins, and it's what Satoshi decided to call this field in the original codebase, so that's the term we still use today.

But it is easier to just think of the ScriptPubKey as the "locking code" on an output.

"ScriptPubKey", "scriptPubKey", and "scriptpubkey" are just different ways of writing the same thing. There's no official way of writing it, although the camel case variant with a lowercase letter for the first word ("scriptPubKey") is the way Satoshi wrote it and seems to be the most prevalent.