Skip to content

Block format

The Nimiq Proof-of-Stake consensus algorithm has micro and macro blocks. Validators produce micro blocks and propose macro blocks. Both types of blocks have different functions in the blockchain. Micro and macro blocks are divided into three sections: header, body, and justification.

  • Header: Contains data of the block itself and commitments to the body and state of the blockchain.
  • Body: The part of the block where transactions or data regarding the staking contract is stored, depending on whether it is a micro or macro block.
  • Justification: Includes necessary data to make the block valid according to the consensus rules and verify the block producer or multi signature.

Micro Blocks

Micro blocks contain user transactions, and each micro block is produced and signed by a validator according to the validator selection. There is also another type of micro block, that is produced when there is a delay in the block production - a skip block.

Micro header

Data fieldDescription
networkThe network ID associated with the block, such as mainnet or devnet.
versionThe block’s version number. A change in the version number implies a hard fork.
block_numberThe block’s number.
timestampThe block's Unix time with millisecond precision.
parent_hashThe hash of the preceding block's header (micro or macro).
seedThe block’s seed. Derived from the preceding block's seed, utilizing the validator key of the block producer, following the algorithm specified in VXEdDSA
extra_dataField reserved for arbitrary data.
state_rootThe root of the Merkle tree representing the blockchain state, acting as a commitment to its current state.
diff_rootThe root of the trie diff tree proof, authenticating the output of the RequestChunk.
body_rootThe root of the Merkle tree representing the body of the block, serving as a commitment to its content.
history_rootThe root of a Merkle Mountain Range covering all transactions in the current epoch.

Micro body

Data fieldDescription
equivocation_proofsEquivocation proofs for this block. This field could be empty as equivocation proofs aren't present in every block.
transactionsContains all the transactions of the block. This field might be empty in blocks without any transactions. (see skip blocks).

Micro justification

Data fieldDescription
Micro(Ed25519Signature)Block producer's signature.
Skip(SkipBlockProof)Contains aggregated signatures for a skip block. This field might be empty as skip blocks might not occur in a batch.

Note that only one of those is added as justification. The block producer signs the block when the micro block is produced within the expected time. But when the micro block isn't produced in the expected time, a SkipBlockProof is added instead.

Macro Blocks

There are two types of macro blocks: election and checkpoint. A new validator list is elected in every election macro block, and the staking contract is updated accordingly. Macro blocks are produced with Tendermint, where a random validator is chosen to propose the new macro block. User transactions are not included in macro blocks.

Macro header

Data fieldDescription
networkThe network ID associated with the block, such as mainnet or devnet.
versionThe block’s version number. A change in the version number implies a hard fork.
block_numberThe block’s number.
roundThe specific round where the block was proposed.
timestampThe block's Unix time with millisecond precision.
parent_hashThe hash of the preceding block's header (micro or macro).
parent_election_hashThe hash of the header from the previous election macro block
interlinkA vector of hashes that establishes a connection to previous blocks divisible by 2^x, facilitating proof of a series of transactions.
seedThe block’s seed. Derived from the preceding block's seed (micro or macro), utilizing the validator key of the block producer, following the algorithm specified in VXEdDSA
extra_dataField reserved for arbitrary data.
state_rootThe root of the Merkle tree representing the blockchain state, acting as a commitment to its current state.
body_rootThe root of the Merkle tree representing the body of the block, serving as a commitment to its content.
diff_rootThe root of the trie diff tree proof, authenticating the output of the RequestChunk.
history_rootThe root of a Merkle Mountain Range covering all transactions in the current epoch.

Macro body

Data fieldDescription
validatorsContains details of the upcoming validator set, including their public keys, reward addresses, and assigned slots. This field is present only when the macro block serves as an election block.
next_batch_initial_punished_setA bitset denoting which slots are forbidden from producing micro blocks or proposing macro blocks in the subsequent batch following this macro block. This information is essential for nodes that don’t have the state as it's usually computed within the staking contract.
transactionsThe reward related transactions of this block.

Macro justification

Checkpoint or election macro blocks contain a TendermintProof as justification.

Data fieldDescription
roundThe specific round where the block was accepted.
sigAggregated signatures of the validators that have signed precommit for the block.

The following figure demonstrates the connection between a macro block and a micro block. Every block, macro or micro, is connected to the previous one by the parent hash and the random seed.

skip block struct

Blockchain format

The blockchain is divided into batches and epochs:

  • Batch: The interval between two macro blocks. A batch consists of several micro blocks, closing on a macro block.
  • Epoch: The interval between two election macro blocks marks an epoch. It starts with the first micro block after an election macro block and ends at an election macro block, including multiple micro blocks and checkpoint macro blocks in between.

blockchain-structure