Skip to content
DonateБГ

Bitcoin from zero

Networking

Bitcoin nodes talk over TCP on port 8333 with a fixed message format. Learn the header, the version handshake and how blocks and transactions are relayed.

By Dimitar Zurnov · Updated 4 Nov 2026
Adapted from Learn Me a Bitcoin by Greg Walker.

Bitcoin nodes talk to each other over the internet with a small binary protocol. Each node opens TCP connections to its peers, usually on port 8333, and sends them messages. Every message has the same header. A handshake opens each connection, and short inventory messages announce new blocks and transactions.

This page covers the bytes on the wire. You need it if you want to write your own client, or if you want to understand what a node sends. You do not need it to use Bitcoin.

Which port does Bitcoin use?

Mainnet nodes listen on TCP port 8333 by default. Test networks use other ports, listed on the magic bytes page. Any language with TCP sockets can open a connection. Your node chooses its own peers, and the node page explains how it finds them.

What does a message look like?

Every message has a 24-byte header followed by a payload. The header says which network the message belongs to, what kind of message it is, how long the payload is, and a checksum that catches damage in transit.

A message is a 24-byte header, then a payload. The header holds the magic bytes, command, length and checksum. Magic bytes (4 bytes) f9 be b4 d9 on mainnet Command (12 bytes) 76 65 72 73 69 6f 6e 00 00 00 00 00 Payload length (4 bytes) 55 00 00 00 = 85 bytes Checksum (4 bytes) 2c 2f 86 f3 Payload The contents of the message, 85 bytes here 7e 11 01 00 00 00 00 00 ... Numbers in the header are little-endian.
The example is the version message on this page. Numbers in the header are little-endian.
Field Size Contents
Magic bytes 4 The network marker, such as f9beb4d9 on mainnet
Command 12 The message name in ASCII, padded with zero bytes
Length 4 The payload size in bytes, little-endian
Checksum 4 The first 4 bytes of SHA-256 applied twice to the payload

A node will not accept a payload larger than 4,000,000 bytes (Bitcoin Core source). Some messages have no payload at all, which is why the checksum of an empty payload is always the same. The short Python function below builds a header. It reproduces the verack header from this page.

import hashlib, struct

def header(magic: bytes, command: str, payload: bytes) -> bytes:
    checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
    return magic + command.encode().ljust(12, b"\x00") + struct.pack("<I", len(payload)) + checksum

print(header(bytes.fromhex("f9beb4d9"), "verack", b"").hex())
# f9beb4d976657261636b000000000000000000005df6e0e2

What does the version message contain?

The first message each side sends is version. It tells the other node the protocol version, which services you offer, the time, and a few addresses. The example below has an empty user agent, so its payload is 85 bytes. It leaves out the relay flag at the end, which BIP 37 added. Bitcoin Core always sends that byte, so a real version message with an empty user agent is 86 bytes.

Field Size Format Example bytes
Protocol version 4 little-endian 7e110100 (70014)
Services 8 bit field, little-endian all zero
Time 8 Unix time, little-endian c515cf6100000000
Remote services 8 bit field, little-endian all zero
Remote IP 16 IPv6, big-endian 00…ffff2e13894a
Remote port 2 big-endian 208d (8333)
Local services 8 bit field, little-endian all zero
Local IP 16 IPv6, big-endian 00…ffff7f000001
Local port 2 big-endian 208d (8333)
Nonce 8 little-endian all zero
User agent 1 compact size, then ASCII 00 (empty)
Last block 4 little-endian all zero
Relay flag 1 1 if you want transactions relayed to you 01 in Core's messages

The services field is a bit field. Bit 0 means the node serves the full chain. Bit 3 means it understands SegWit witness data. The IP fields use IPv6 form, so an IPv4 address appears after ffff. The ports are big-endian, unlike the other numbers.

How does the handshake work?

Two messages open every connection: version, then verack, which means version acknowledged. Each side sends its own version, and each side replies with verack. The order matters. Until both sides have exchanged version messages, other messages are not accepted. A peer that gets the order wrong drops the connection. Repeated mistakes can get the sender's address banned for a while.

Our node sends version, the peer replies with version and verack, and we finish with verack. Your node Peer node 1. version (ours) 2. version (theirs) 3. verack (theirs) 4. verack (ours) Handshake complete
After the fourth message, either side can send any other message.

The verack message has no payload, so its header is the same every time. On mainnet it is f9beb4d976657261636b000000000000000000005df6e0e2.

How do nodes share transactions and blocks?

Nodes do not send every new transaction or block unprompted. They announce them with an inv message. It lists hashes and a type for each item. The receiver asks for the items it lacks with getdata, and the sender answers with a tx or block message. This saves bandwidth, because a small announcement tells the peer what exists without sending it all.

A node announces a hash with inv, the peer asks for it with getdata, and the full transaction arrives in a tx message. Peer node Your node inv inv: 1 transaction hash getdata getdata: the same hash tx tx: the full transaction Each item in inv or getdata Type (4 bytes, little-endian), then hash. 01000000 transaction (txid) 02000000 block hash 01000040 transaction with witness 02000040 block with witness
The announcement is small, so a node sends the full data only when a peer asks for it.

Each item in an inv or getdata message is an inventory vector. Its type is a 4-byte little-endian number:

  • 1 (01000000) is a transaction hash, the txid.
  • 2 (02000000) is a block hash.
  • 01000040 asks for a transaction with its witness data. Use it for SegWit transactions when you need the signatures.
  • 02000040 asks for a block with its witness data.

The payload starts with a count, written as a compact size. The getdata payload has the same format as inv, so a node can reply with the same bytes to ask for everything an announcement listed.

What are compact blocks?

Sending a whole block to every peer wastes bandwidth, because most of its transactions are already in the peers' mempools. BIP 152 solves this with compact block relay. The sender announces the block header and a list of short transaction IDs. The receiver rebuilds the block from its own mempool and asks only for the transactions it is missing.

What changed in newer Bitcoin Core versions?

Two things differ from the plain examples above. Bitcoin Core 27.0, released on 16 April 2024, turned on the version 2 transport from BIP 324 by default. That transport encrypts the connection. To talk to a current node with the plain messages on this page, start it with -v2transport=0.

The protocol version has moved on too. The example uses 70014, from an older release. Bitcoin Core 26.0 through 31.2 advertise 70016, which added wtxid relay in BIP 339. Bitcoin Core 32.0 and later advertise 70017, which added feature negotiation. The current release, 32.1, uses 70017. The value is PROTOCOL_VERSION in src/node/protocol_version.h, so check it at the release you run.

How do you keep a connection open?

Peers send ping messages to check that you are still there. Since protocol version 60001 (BIP 31), a ping carries a random 8-byte nonce as its payload. Your reply is a pong with the same nonce. A peer that stops getting timely pongs eventually drops the connection.

Can you try it yourself?

Yes. Any language with a TCP socket can send a version message and read the reply. Start with a node on 127.0.0.1, follow the handshake, and check each header against the table near the top of this page. The full list of messages is on the Bitcoin Wiki. Once you can complete a handshake, the other messages follow the same pattern. For the node itself, see node. For the blocks and transactions you receive, see block and transaction.

In this section

  1. 1Running a full nodeA bitcoin full node checks every block and transaction itself. Learn the node types, what it needs in disk and RAM, and how to run a bitcoin node.
  2. 2Magic bytesBitcoin magic bytes are the 4-byte marker at the start of every P2P message. Mainnet uses f9beb4d9, and each test network has its own value.

Something look wrong? Tell us