Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Serialization

Bitcoin protocol objects are byte strings with fixed field order. Unless a field table states otherwise, $E_T$ serializes integers in little-endian byte order, vectors with a CompactSize element count, and byte vectors with a CompactSize byte length followed by exactly that many bytes.

Fixed-width primitives

PrimitiveWidthSerialization rule
uint8 / int81 byteByte value as stored.
uint16 / int162 bytesLeast significant byte first.
uint32 / int324 bytesLeast significant byte first.
uint64 / int648 bytesLeast significant byte first.
byte[n]$n$ bytesExactly the given bytes, in index order.
bool1 byteZero is false; nonzero is true unless a field table restricts the value.
uint16020 bytes160-bit hash value.
uint25632 bytes256-bit hash value. Display hex commonly reverses these bytes.

Fixed-width integer fields are serialized in little-endian byte order unless a field table explicitly states otherwise (sources: bitcoin-core-v31).

CompactSize

Bitcoin transaction and block structures use CompactSize integers to encode counts and byte-vector lengths. CompactSize is canonical: a decoder rejects a value encoded with a longer form than necessary.

Value rangeEncodingCanonicality rule
$0 <= n < 253$one byte: $n$First byte is less than 0xfd.
$253 <= n <= 0xffff$0xfd followed by uint16Decoded value must be at least 253.
$2^16 <= n <= 2^32-1$0xfe followed by uint32Decoded value must be at least 0x10000.
$2^32 <= n <= 2^64-1$0xff followed by uint64Decoded value must be at least 0x100000000.

A parser rejects non-canonical CompactSize encodings and any decoded count or length that exceeds the enclosing field’s rule.

Constructors

ConstructorSerialized formUsed for
vector<T>`compactSize count
varbytes`compactSize length
string`compactSize length
witnessStack`compactSize itemCount

Scripts, signatures, public keys, witness items, and network payload fields reuse varbytes in different contexts. Parsing bytes into opcodes, signatures, keys, or scripts is a later semantic step.

For transactions and blocks, $E_0(x)$ is the serialization with witness data stripped, and $E_w(x)$ is the serialization including witness data where such data is defined. Define:

$$ strippedSize(x) = |\mathrm{E}{0}(x)|, \qquad totalSize(x) = |\mathrm{E}{w}(x)|. $$

The consensus weight formula is:

$$ weight(x) = 3 \cdot strippedSize(x) + totalSize(x). $$

For relay and fee accounting, virtual transaction size is the integer ceiling of weight divided by witness scale:

$$ vsize(tx) = \left\lfloor \frac{weight(tx) + \text{\code{WITNESS_SCALE_FACTOR}} - 1} {\text{\code{WITNESS_SCALE_FACTOR}}} \right\rfloor. $$

Block consensus enforces MAX_BLOCK_WEIGHT against weight(block) (sources: bip-0141,bitcoin-core-v31).