TeachMeBitcoin

What is Script Serialization

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

What is Script Serialization?

Bitcoin Script is ultimately a sequence of bytes. The process of encoding Script data into its binary representation is called serialization. Every opcode, every data push, and every script is serialized into raw bytes when stored in a transaction.

Opcode Bytes

Each opcode is a single byte. Bitcoin Script defines 256 possible byte values, though not all are currently used:

0x00 → OP_0 / OP_FALSE
0x51 → OP_1
0x52 → OP_2
...
0x60 → OP_16
0x61 → OP_NOP
0x63 → OP_IF
0x76 → OP_DUP
0x87 → OP_EQUAL
0x88 → OP_EQUALVERIFY
0xa9 → OP_HASH160
0xac → OP_CHECKSIG
0xae → OP_CHECKMULTISIG

Data Push Serialization

When a script needs to push raw data (like a public key or signature), it uses a push opcode followed by the data bytes:

// Pushing 20 bytes:
0x14 <20 bytes>
// 0x14 = decimal 20 = "push the next 20 bytes"

// Pushing 33 bytes (compressed public key):
0x21 <33 bytes>
// 0x21 = decimal 33

// Pushing 71 bytes (typical DER signature):
0x47 <71 bytes>
// 0x47 = decimal 71

For data items 1–75 bytes, the byte itself serves as the push opcode. For larger items:

// 76–255 bytes:
0x4c <1-byte-length> <data>  // OP_PUSHDATA1

// 256–65535 bytes:
0x4d <2-byte-length-LE> <data>  // OP_PUSHDATA2

// 65536+ bytes:
0x4e <4-byte-length-LE> <data>  // OP_PUSHDATA4

Full Transaction Script in Hex

Here is a real P2PKH scriptPubKey and how it serializes:

Script: OP_DUP OP_HASH160 <20-byte-hash> OP_EQUALVERIFY OP_CHECKSIG

Hex:    76 a9 14 {40 hex chars} 88 ac

Breakdown:
76 → OP_DUP
a9 → OP_HASH160
14 → push 20 bytes (0x14 = 20 decimal)
{20 bytes} → the public key hash
88 → OP_EQUALVERIFY
ac → OP_CHECKSIG

Script Lengths and varints

In a transaction, scripts are prefixed with their length encoded as a varint (compact size integer):

// Script length encoding:
0x00–0xfc: 1 byte (for scripts 0–252 bytes)
0xfd <2 bytes LE>: 3 bytes (for scripts 253–65535 bytes)
0xfe <4 bytes LE>: 5 bytes (for scripts 65536–4294967295 bytes)
0xff <8 bytes LE>: 9 bytes (rarely used)

// Example: 25-byte P2PKH scriptPubKey:
19 76a914{hash}88ac
// 0x19 = 25 decimal, then the 25 bytes

CScript in Bitcoin Core

In Bitcoin Core's C++ codebase, scripts are represented as CScript objects, which are essentially std::vector<unsigned char> with helper methods for building and parsing:

// Building a P2PKH scriptPubKey:
CScript scriptPubKey;
scriptPubKey << OP_DUP << OP_HASH160 << ToByteVector(pubKeyHash)
             << OP_EQUALVERIFY << OP_CHECKSIG;

// Building a P2PKH scriptSig:
CScript scriptSig;
scriptSig << ToByteVector(sig) << ToByteVector(pubKey);
☕ Help support TeachMeBitcoin

TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!