The VarInt Specification
The VarInt Specification
To correctly parse a Bitcoin transaction, you must follow the strict thresholds defined in the VarInt (CompactSize) specification. The logic is simple but requires careful byte-reading.
1. The Threshold Rules
When a parser encounters a VarInt field, it reads the first byte and follows this logic:
| First Byte | Meaning | Data to Read Next |
|---|---|---|
| < 0xFD | The value is the byte itself. | 0 Bytes |
| == 0xFD | The value is a 16-bit integer. | 2 Bytes (Little Endian) |
| == 0xFE | The value is a 32-bit integer. | 4 Bytes (Little Endian) |
| == 0xFF | The value is a 64-bit integer. | 8 Bytes (Little Endian) |
2. Little Endian Requirement
Except for the 1-byte case, all subsequent bytes must be read in Little Endian order.
-
Example: A script length of 512 bytes.
-
512 in hex is
0x0200. -
Serialized:
FD 00 02(MarkerFD+ LE bytes00 02).
3. Handling Zero
The number zero is a valid VarInt. It is represented as a single byte: 0x00. You will see this in transactions with zero outputs (rare) or empty scripts.
4. Avoiding Redundancy
A value like 10 could technically be represented as FD 0A 00 (the 3-byte version). However, the Bitcoin consensus rules require Canonical Encoding.
-
If a number can fit in 1 byte, it must be 1 byte.
-
If you use a 3-byte VarInt to store a 1-byte value, your transaction is "Non-Standard" and will be rejected by most nodes.
5. Security: The "OOM" Attack
Parsers must be careful when reading the output count VarInt.
-
If an attacker sends a transaction claiming to have 4 billion outputs (
FE FF FF FF FF), a poorly written node might try to allocate gigabytes of RAM to store those outputs before realizing they don't actually exist in the packet. -
Modern nodes verify the packet size matches the claimed VarInt count before allocating memory.
| Decimal Value | VarInt Hex | Total Size |
|---|---|---|
| 252 | FC |
1 Byte |
| 253 | FD FD 00 |
3 Bytes |
| 65,535 | FD FF FF |
3 Bytes |
| 65,536 | FE 00 00 01 00 |
5 Bytes |
In the next section, we will compare VarInt vs. Fixed-Width Integers.
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: