TeachMeBitcoin

The P2P Version Message: Byte Layout and Payload Specifications

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

The P2P Version Message: Byte Layout and Payload Specifications

The version message is the foundational payload that initiating peers transmit upon opening a TCP connection. It acts as the negotiation contract, detailing the node’s protocol capabilities, system time, network addresses, user-agent details, and block synchronization heights.

This guide details the complete byte serialization layout and field specifications of the standard version message payload.


1. The Serialization Blueprint

The version payload contains 11 distinct fields, varying in size. Below is the precise sequential schema:

Offset (Bytes) Field Name Data Type Endianness Description
0 - 3 Version int32_t Little Endian Identifies the protocol version (e.g., 70016).
4 - 11 Services uint64_t Little Endian Bitfield of service capabilities (e.g., NODE_NETWORK = 1).
12 - 19 Timestamp int64_t Little Endian Epoch system timestamp in seconds of the sending node.
20 - 45 Addr Recv net_addr Big Endian Network address details of the receiving node (peer).
46 - 71 Addr From net_addr Big Endian Network address details of the sending node (self).
72 - 79 Nonce uint64_t Little Endian Cryptographic random number to identify self-connections.
80 - ? User Agent var_str Raw (ASCII) The name of the client software (e.g., /Satoshi:25.0.0/).
? - ? Start Height int32_t Little Endian Current active tip block height of the sending node.
? Relay bool Raw Flag (0 or 1) indicating if node should receive unconfirmed txs.

2. Detailed Field Analysis

A. Network Address Serialization (net_addr)

To support unified IPv4 and IPv6 networks inside a standard schema, net addresses are always serialized as 26-byte structs:

IPv4-to-IPv6 Mapping Format

IPv4 addresses are padded inside the 16-byte IP field using the standard mapping syntax:

$$\text{IPv4 Mapping: } \underbrace{\texttt{00 00 ... 00}}{10\text{ bytes}} \underbrace{\texttt{FF FF}}{2\text{ bytes}} \underbrace{\text{IP Address}}_{4\text{ bytes}}$$

For example, 127.0.0.1 is serialized as: $$\texttt{00 00 00 00 00 00 00 00 00 00 FF FF 7F 00 00 01}$$

B. User Agent Variable String (var_str)

The User Agent is stored as a variable-length string. It starts with a CompactSize integer (1–9 bytes) defining the length of the string, followed by the ASCII characters.

For example, the string /Satoshi:25.0.0/ is 16 bytes:

C. Self-Connection Detection via Nonce

When a node broadcasts its IP, it might accidentally initiate a connection to itself. To prevent infinite loops:

☕ 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!