- The candidate block
- The Merkle tree: summarizing a large set of transactions
- Block header
You've now understood how a Bitcoin transaction works, and the role of the blockchain. However, before we look in more detail at how proof-of-work works, there's still one essential step that the miner must perform: the construction of a candidate block. Let's find out together what a candidate block is and how the miner constructs it, before embarking on the search for a valid proof.
The candidate block
Miners have to build their blocks themselves before trying to mine them. Each miner, in turn, constructs what is known as a candidate block from the transactions pending in his mempool. Building a candidate block therefore consists of:
- choose which transactions to include;
- organize these transactions in a way that is compatible with Bitcoin rules;
- produce the block's metadata, stored in its header.
The choice of transactions follows a simple economic logic: a block has a capacity limited by the Bitcoin protocol, so the miner seeks to maximize what he earns for this space. He selects as a priority the transactions offering the highest fees relative to the space they occupy in the block (this is known as the "fee rate", expressed in sats/vB). The details of fees will be dealt with later; just remember the idea of sorting by space efficiency.
A Bitcoin block therefore consists of two main parts:
- a list of transactions;
- a block header, which serves, in a way, as the block's identity card.
The header is essential, as it is used as the basis for the proof-of-work: in Bitcoin, you don't mine an entire block directly; you mine only the header of a block, which summarizes the information needed to link the block to the chain and commit its contents. To enable the header to represent all transactions, Bitcoin uses a cryptographic tool: the Merkle tree.
The Merkle tree: summarizing a large set of transactions
Listing all the transactions in the header would be impossible: a block can contain thousands of transactions, while the header has a fixed size (80 bytes). The solution is therefore to calculate a unique hash that depends on all the transactions in the block: this is the Merkle root.
The principle is as follows:
- the cryptographic fingerprint (hash) of each transaction is calculated;
- these hashes are paired, concatenated, and then hashed again to form a new layer of hashes;
- this process is repeated until a single final hash is obtained: the Merkle root.
So, if a single transaction changes, even by a single bit, the result is a modification of its fingerprint, which propagates to the Merkle root. This root is included in the block header. So modifying a past transaction means modifying the block header in which it is included, and therefore the block footprint, and then the link with subsequent blocks.
Since SegWit, we've separated the signatures from the rest. So, in reality, there are 2 Merkle trees nested within each block. This separation has consequences for the way we count the size of a block and for certain cryptographic commitments, but the basic idea remains the same: the header must commit, in a compact way, all the contents of the block.
Block header
The block header is 80 bytes long and contains exactly 6 fields. It is these six elements that will be hashed when searching for a proof of work (see next chapter):
-
The version (
version): This indicates which rules or update signals the block adheres to. It serves as a mechanism for maintaining protocol compatibility and evolution. -
Previous block hash (
previousblockhash): This is the hash of the previous block's header. This is what links the blocks together. Without this field, we'd have independent blocks. By including the hash of the previous block's header, we obtain a chain, where each new block builds on the previous one. -
Merkle root (
merkleroot): This is the fingerprint of all the transactions in the block (via the Merkle tree). It links the header to the content: if the miner modifies the selection or order of transactions, the root changes. -
Time stamp: This is a timestamp (Unix time) chosen by the miner (with validity constraints), which must indicate when the block was mined. It doesn't have to be perfectly accurate to the second, but it must meet certain conditions to remain acceptable to the network.
-
Encoded difficulty target (
nbits): This field encodes the current difficulty target. We'll go into more detail in the chapter on difficulty, but remember that this parameter is part of the header. -
Nonce (
nonce): This is a value that the miner can freely modify. It serves as an adjustable variable during proof-of-work. I'll explain its role in more detail in the next chapter, but it's important to understand that the nonce is part of the block header and is designed to allow successive attempts.
To make this easier to visualize, here's an example of a block header in hexadecimal format (80 bytes):
00e0ff3f5ffe3b0d9247dc437e18edc19252e4517cee941752d501000000000000000000206b de3a10826e2acb2f28fba70463601c789293d0c9c4348d7a0d06711e97c0bcb13a64b2e00517 43f09a40
Here is a field-by-field breakdown:
version: 00e0ff3f previousblockhash: 5ffe3b0d9247dc437e18edc19252e4517cee941752d501000000000000000000 merkleroot: 206bde3a10826e2acb2f28fba70463601c789293d0c9c4348d7a0d06711e97c0 time: bcb13a64 nbits: b2e00517 nonce: 43f09a40
This candidate block header, constructed by the miner, forms the basis of their work. When searching for a valid proof-of-work, it's not the entire list of transactions that is directly hashed in a loop, but rather this 80-byte block, which contains everything needed to link the block to the past and commit its contents, while also including the parameters necessary for the mining mechanism, which we'll explore in the next chapter.
Quiz
Quiz1/5
min1012.2
What economic criterion guides a miner's choice of transactions?