All message contain following basic fields:
| Element | Data type | Bytes | Description |
|---|---|---|---|
| magic | uint32 | 4 | 0x42042042, Indicating that this is a message. |
| type | VarInt | >=1, <= 8 | Usually 1 bytes |
| length | uint32 | 4 | length of the message. Currently ignored. |
| checksum | uint32 | 4 | CRC32 checksum. |
All messages have a fixed message type. Additional fields of specialized messages will be added behind.
This message type = 0 sends out the status of this node, including it's protocol version, peer address, genesis block hash, and the hash of the latest block in its blockchain (the head).
| Element | Data type | Bytes | Description |
|---|---|---|---|
| version | uint32 | 4 | version of the protocol |
| peer address | uint32 | 4 | Three address types; see below |
| genesis hash | Hash | 32 | Hash of Genesis block |
| head hash | Hash | 32 | Hash of latest block in node's blockchain. |
Three addresses can be used, a Web Socket address, a Web RTC address or a pain/dumb address.
| Element | Data type | Bytes | Description |
|---|---|---|---|
| protocol | uint8 | 1 | 1 |
| service mask | uint32 | 4 | 0 none, 1 nano, 2 light, 4 full |
| timestamp | uint64 | 8 | Used by other nodes to calculate offset. |
| net address | string | > 8 - 16 | IPv4 address as string |
| host | string | >10 | Hostname. |
| port | number | 2 | Port number for Web Socket Connector to listen to. |
| Element | Data type | Bytes | Description |
|---|---|---|---|
| protocol | uint8 | 1 | 2 |
| services | uint32 | 4 | see previous |
| timestamp | uint64 | 8 | see previous |
| net address | string | > 8 - 16 | see previous |
| signal ID | uint16 | 2 | Signaling ID |
| distance | uint8 | 1 | 0: self, 1: direct connection, 2: 1 hop |
| Element | Data type | Bytes | Description |
|---|---|---|---|
| protocol | uint8 | 1 | 0 |
| services | uint32 | 4 | see previous |
| timestamp | uint64 | 8 | see previous |
| net address | uint16 | 2 | see previous |
| id | uint64 | 8 |
A typical situation:
- Node A enters the network and needs to synchronize
- B sends out a
get blocksmessage - B receives and sends an
relay inventorywith hashes of blocks that B considers useful for A - B compares the list with the blocks it has already
- B uses
get datato request the data for the blocks it doesn't have yet.
Similarily
- Node A wants to update it's mempool and
- A sends out a
mempoolmessage - Node B receives and sends an
relay inventorymessage with blocks and transaction they have in their mempool - ... same like previous
| Element | Data type | Bytes | Description |
|---|---|---|---|
| count | uint16 | 2 | Number of hashes requested |
| locators | [Hash] | count * 32 | List of block hashes from where to start sending more blocks. The receiving node will start sending from the first block it finds in it's blockchain. |
| max inventory size | uint8 | 2 | The number of blocks that are been asked. |
| direction | uint8 | 1 | 1 forward (blocks afterwards); 2 backwards (previous blocks). |
The response can be type = 6 for blocks, 7 for header, 8 for transaction, or type = 4 if the requested inventory could not be found.
Announcing it's blocks and transmissions, a node sends out an inventory message:
| Element | Data type | Bytes | Description |
|---|---|---|---|
| count | uint16 | 2 | |
| hashes | [Type+Hash] | count * 36 | Depending on type, hashes of transactions or blocks |
Request headers via type = 3, and block or transactions data via type = 2
| Element | Data type | Bytes | Description |
|---|---|---|---|
| count | uint16 | 2 | |
| hashes | [Type+Hash] | count * 36 | Depending on type, hashes of transactions or blocks |
The type for each element in the hashes list can be 0..2: error, transaction, and block. 0 is not being used.
This message is used to send one block at a time (in serialized form).
| Element | Data type | Bytes | Description |
|---|---|---|---|
| block | Block | <= 1MB | Full block |
This message is used to send one header at a time (in serialized form).
| Element | Data type | Bytes | Description |
|---|---|---|---|
| header | Header | 162 | Block header |
This message is used to send one header at a time (in serialized form).
| Element | Data type | Bytes | Description |
|---|---|---|---|
| transaction | Transaction | XXX | Transaction |
This message is used to request peers to relay their inventory/mempool content. No additional fields, type = 9, cf. message types.
This message is used to signal to a peer that something they sent to the node was rejected and the reason why it was rejected.
| Element | Data type | Bytes | Description |
|---|---|---|---|
| message type | VarInt | 1 | message type |
| code | uint8 | 1 | Reject message codes |
| reason length | uint8 | 1 | |
| reason | string | length | The reason why. |
| extra data length | uint16 | 2 | |
| extra data | raw | length | Extra information that might be useful to the requester. |
This message is used to subscribe to messages from the node that this message is sent to, two version exist, "addresses" and "min fee".
| Element | Data type | Bytes | Description |
|---|---|---|---|
| subscription type | uint8 | 1 | 2 for "addresses" or 3 for "min fee" |
Type "addresses" adds:
| Element | Data type | Bytes | Description |
|---|---|---|---|
| address count | uint16 | 2 | Number of addresses |
| addresses | [Address] | count * 20 | List of addresses to subscribe to |
Type "min fee" adds:
| Element | Data type | Bytes | Description |
|---|---|---|---|
| fee | uint64 | 8 | Min fee per byte in Satoshi required to subscribe |
This message is used to relay the addresses to other peers.
Ask for for addresses to peers that use the specified protocol and provide the specified services.
| Element | Data type | Bytes | Description |
|---|---|---|---|
| protocol mask | uint8 | 1 | 0 dumb, 1 ws, 2 rtc |
| service mask | uint32 | 4 | 0 none, 1 nano, 2 light, 4 full |
A list of address in return for a get addresses message.
| Element | Data type | Bytes | Description |
|---|---|---|---|
| address count | uint16 | 2 | Number of addresses |
| addresses | [Address] | count * 20 | List of addresses of other peers in the network. |
This messages are used to make sure that the other peer node is available still.
| Element | Data type | Bytes | Description |
|---|---|---|---|
| type | uint16 | 2 | 22 for ping, 23 for pong (response) |
| ... | |||
| nonce | uint32 | 4 | Make pings and pongs unique, avoid replay |
Signaling is needed for the browser clients to establish a connection with other clients of the same type.
| Element | Data type | Bytes | Description |
|---|---|---|---|
| sender id | raw | 16 | 16 bytes address of sender |
| recipient id | raw | 16 | 16 bytes address of recipient |
| nonce | uint32 | 4 | aviod replay |
| time to live | uint8 | 1 | TTL |
| flags | uint8 | 1 | unroutable: 0x1, TTL exceeded: 0x2 |
| payload length | uint16 | 2 | |
| payload | raw | length | signed data, cf. signature |
| sender public key | uint32 | 32 | if payload payload length > 0 |
| signature | raw | 64 | if payload payload length > 0 |
To get chain proof, sent a basic message with type = 40.
The response (type = 41) contains blocks and headers.
| Element | Data type | Bytes | Description |
|---|---|---|---|
| block count | uint16 | 2 | amount of blocks attached |
| blocks | Block | max count * 1MB | full blocks |
| header count | uint16 | 2 | amount of headers attached |
| header chain | Header | count * 162 | headers |
A node can ask (type = 42) for proofs for certain accounts by using the hash of it's accounts tree root.
| Element | Data type | Bytes | Description |
|---|---|---|---|
| block hash | Hash | 32 | hash of block these accounts should be in |
| address count | uint16 | 2 | |
| addresses | Address | count * 20 | Addresses to be checked |
To get a response (type = 43) with following data:
| Element | Data type | Bytes | Description |
|---|---|---|---|
| block hash | Hash | 32 | block these accounts are in |
| has proof | uint8 | 1 | 1 means the proof is attached, otherwise 0 |
| proof count | uint16 | 2 | |
| proofs | AccountsTreeNode | count * variable size | Proofs for the requested accounts as nodes from the Merkle tree. |
To request a paricular chunk of of account tree nodes (type = 44)
| Element | Data type | Bytes | Description |
|---|---|---|---|
| block hash | Hash | 32 | hash of block these accounts should be in |
| start prefix length | uint8 | 1 | |
| start prefix | string | length | Defining the part of the tree where accounts are needed from. |
The node should respond a message type = 45:
| Element | Data type | Bytes | Description |
|---|---|---|---|
| block hash | Hash | 32 | hash of block these accounts should be in |
| has chunks | uint8 | 1 | 1 means chunks are attached |
| node count | uint16 | 2 | |
| nodes | AccountsTreeNode | count * variable size | Account tree nodes from the requested part of the tree. |
| proof count | uint16 | 2 | |
| proofs | AccountsTreeNode | count * variable size | Account tree nodes as proof |
This message is used to send one transaction at a time (in serialized form) but can also contain an accountsProof.
| Element | Data type | Bytes | Description |
|---|---|---|---|
| block hash | Hash | 32 | Hash of block the transactions belong to |
| transactions count | uint16 | 2 | count of transactoins being requested |
| transactions hash | [Transaction] | count * 20 | Hashes of transactions being requested |
| Element | Data type | Bytes | Description |
|---|---|---|---|
| block hash | Hash | 32 | Hash of block the transactions belong to |
| has proof | uint8 | 1 | 1 means the proof is attached, otherwise 0 |
| proof length | uint16 | 2 | if has proof was set |
| proof | raw | proof length | the proof if has proof was set |
Get transactions receipts via message type = 49
| Element | Data type | Bytes | Description |
|---|---|---|---|
| address | Address | 20 | Address of transaction |
Receive transactions receipts in a type = 50 message:
| Element | Data type | Bytes | Description |
|---|---|---|---|
| receipt count | uint16 | 2 | |
| receipts | 2x Hash | 64 | transaction hash and block hash |