§ 07 · Blocks
Merkle root
One 32-byte hash that vouches for every transaction in the block
On this page 6 sections
The Merkle root is how a 108-byte header vouches for a block full of transactions.
Every transaction ID in the block is hashed in pairs, the pairs are hashed in pairs, and so on, until one hash is left. That hash goes into the header. Change, add, remove or reorder a single transaction and the root comes out different, so the header no longer matches the block.
The tree itself is explained step by step in Merkle trees. This page is about the header field: where it sits, what it covers and what it doesn’t, and the part it plays in Pearl’s mining.
Try it
Add, edit or reorder transactions and watch the root recompute.
Where is it in the header?
- Size
- 32 bytes
- Type
- SHA256d Merkle root of the txids
- Format
- Internal byte order (shown reversed)
| Field | Bytes | Value |
|---|---|---|
| Version header.version | 4 @0 | 0x20000000 int32 LE. BIP-9 style 0x20000000 since block 1; no consensus meaning in Pearl. |
| Previous block header.prevBlock | 32 @4 | eb555c52c695cfa0b2ad27f0d1f96ca55f1dc32d864e13218b4bd9041b969c99 Hash of the parent block, stored byte-reversed; shown in display order. |
| Merkle root header.merkleRoot | 32 @36 | c6c21c0c4204b9f39e17d7f79811aff53eac88ea0d80fcdeffdad96ba3fa8963 Root of the SHA256d Merkle tree of this block’s txids, stored byte-reversed. |
| Time header.timestamp | 4 @68 | 1792513562 (2026-10-20 16:26:02 UTC) uint32 LE Unix seconds. Must be at least 1 s after the parent and at most 5 min in the future. |
| Bits header.bits | 4 @72 | 0x176af3a6 Compact target. Difficulty 40157376.49334089. The certificate's jackpot hash (not this header's hash) must meet it. |
| Proof commitment header.proofCommitment | 32 @76 | 49e67ac73638201f2815a24689b8b1df672f9176df2ee232b00c1632fda3524d SHA256d(LE32(certificate version) ‖ public data). Replaces Bitcoin’s nonce: Pearl headers have no nonce. |
Bytes 36 to 67. In block 130,827 they are 6389faa3…0c1cc2c6, which an explorer shows reversed as c6c21c0c4204b9f39e17d7f79811aff53eac88ea0d80fcdeffdad96ba3fa8963. That block has 6 transactions, so its tree has three levels above the leaves:
A node rebuilds the tree from the transactions it received and compares the result with the header. If they differ, the block is invalid, before any expensive checks run.
What does the simplest tree look like?
One leaf. If a block contains only its coinbaseCoinbase transaction: The first transaction in every block. It has no real inputs: it creates the block's new PRL and pays them, plus the fees, to the miner., the Merkle root is the coinbase’s txidTXID: A transaction's ID: the double SHA-256 hash of the transaction without its witness, shown with its bytes reversed..
Block 1 is such a block. Its coinbase’s txid is 36b18b26fba6b71149951d88904945c64137e74b250de8d76c4beded90560be2, and here it is in the header, stored reversed:
| Field | Bytes | Value |
|---|---|---|
| Version header.version | 4 @0 | 0x20000000 int32 LE. BIP-9 style 0x20000000 since block 1; no consensus meaning in Pearl. |
| Previous block header.prevBlock | 32 @4 | a18d3093b7ff618f0cdd073fa3d10374e2e0105fe7ef53ff48b55f41c58dadd7 Hash of the parent block, stored byte-reversed; shown in display order. |
| Merkle root header.merkleRoot | 32 @36 | 36b18b26fba6b71149951d88904945c64137e74b250de8d76c4beded90560be2 Root of the SHA256d Merkle tree of this block’s txids, stored byte-reversed. |
| Time header.timestamp | 4 @68 | 1777280401 (2026-04-27 09:00:01 UTC) uint32 LE Unix seconds. Must be at least 1 s after the parent and at most 5 min in the future. |
| Bits header.bits | 4 @72 | 0x1b00ffff Compact target. Difficulty 1. The certificate's jackpot hash (not this header's hash) must meet it. |
| Proof commitment header.proofCommitment | 32 @76 | f088903569c4b163d26558d51da7e69e38c94b9018e09e88c1789fc67b2c70a6 SHA256d(LE32(certificate version) ‖ public data). Replaces Bitcoin’s nonce: Pearl headers have no nonce. |
This is common on Pearl. In a 200-block sample taken on 2026-10-20, 107 blocks contained nothing but their coinbase.
What does the root cover, and what not?
It covers the txids. A txid is the hash of a transaction without its witness data, the signatures that unlock its inputs. So the header’s Merkle root doesn’t directly cover signatures.
Witnesses are covered one step removed, exactly as in Bitcoin’s segwit:
-
A second tree over wtxids
The node builds another Merkle tree over every transaction’s wtxidWTXID: The witness transaction ID: like the TXID, but the hash covers the witness too. (the hash including witness data), with the coinbase’s set to 32 zero bytes.
-
Its root goes into the coinbase
SHA256d of that root and a 32-byte reserved value is written into a coinbase output starting
6a24aa21a9ed: the witness commitmentWitness commitment: An OP_RETURN output in the coinbase that commits to every witness in the block: 6a24aa21a9ed followed by SHA256d(witness Merkle root ‖ a 32-byte value from the coinbase witness).. -
The coinbase is under the main root
The coinbase’s txid is the first leaf of the header’s tree, so the header vouches for the witness commitment, which vouches for every witness.
Here is the witness commitment in block 130,825’s coinbase, output 1:
| Field | Bytes | Value |
|---|---|---|
| Version version | 4 @0 | 2 int32 little-endian. Pearl wallets and pearld coinbases use version 1; relay policy accepts 1-2. |
| Marker marker | 1 @4 | 0x00 Segwit marker (BIP-144): says witness data follows the outputs. |
| Flag flag | 1 @5 | 0x01 Witness flag; 0x01 is the only value Pearl accepts. |
| Input count vin.length | 1 @6 | 1 CompactSize number of inputs. |
| Previous txid vin[0].txid | 32 @7 | 0000000000000000000000000000000000000000000000000000000000000000 All zeros: this input creates new coins (coinbase). |
| Output index vin[0].vout | 4 @39 | 0xffffffff 0xffffffff together with a zero txid marks a coinbase. |
| scriptSig length vin[0].scriptSig.length | 1 @43 | 39 CompactSize length of the scriptSig. |
| Coinbase script vin[0].scriptSig | 39 @44 | 0309ff01048393d76a2f706f6f6c2e6b7279707465782e636f6d2f1550cad31e016e7bf00f2ecb Coinbase data. It starts with the block height 130825 (BIP-34, required in every Pearl block), then anything the miner likes. |
| Sequence vin[0].sequence | 4 @83 | 0xffffffff Final (0xffffffff): no RBF signal, no relative locktime, and locktime is ignored for this input. Pearl wallets use this. |
| Output count vout.length | 1 @87 | 2 CompactSize number of outputs. |
| Amount vout[0].value | 8 @88 | 223,838,373,068 grains (2238.38373068 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains). |
| Script length vout[0].scriptPubKey.length | 1 @96 | 34 CompactSize length of the locking script. |
| Locking script vout[0].scriptPubKey | 34 @97 | prl1puv0gqv4x0wd0ylwz086y3sqrg4a6umza9r08aecehjrmdqq7mctsmqaqsh OP_1 OP_PUSHBYTES_32 <output key Q>: a Taproot output. |
| Amount vout[1].value | 8 @131 | 0 grains (0.00000000 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains). |
| Script length vout[1].scriptPubKey.length | 1 @139 | 38 CompactSize length of the locking script. |
| Locking script vout[1].scriptPubKey | 38 @140 | witness commitment 78cc1a61dcfcee9c59ddd9f4d56a98764c071e077bcc36fe9d1cf0aad50ebac3 OP_RETURN aa21a9ed ‖ SHA256d(witness Merkle root ‖ nonce): the BIP-141 witness commitment. |
| Witness items witness[0].length | 1 @178 | 1 Number of witness stack items for input 0. |
| Witness reserved value length witness[0][0].length | 1 @179 | 32 CompactSize length of this witness item. |
| Witness reserved value witness[0][0] | 32 @180 | 0000000000000000000000000000000000000000000000000000000000000000 The coinbase witness is one 32-byte value (the witness-commitment nonce); pearld uses zeros. |
| Locktime locktime | 4 @212 | 0 0: no time lock. |
A coinbase-only block can leave the commitment out: it has no witnesses to commit to. Some Pearl miners do, and others include it anyway.
The certificate is not under the Merkle root. It isn’t a transaction. It is tied to the header through the last field, the proof commitment, which hashes the certificate’s version and public data.
Why does the Merkle root matter to miners?
Because it is one of the inputs to the mining puzzle. The first 76 bytes of the header, Merkle root included, are hashed into the job keyJob key: A BLAKE3 hash of the block template (the header minus its proof commitment) and the mining settings. All of the puzzle's randomness flows from it, tying the work to one block., and the job key seeds all of the noise a miner must add to its matrices.
So any change to the block’s transactions gives the miner a completely new puzzle:
- a new transaction from the mempool changes the root;
- so does changing a few bytes of the coinbase. Pools put an extranonceExtranonce: Free bytes a miner or pool puts in the coinbase scriptSig, often a counter or a pool tag. Changing them changes the coinbase txid and so the block's Merkle root. there, as in Bitcoin, and on Pearl every new extranonce means a fresh job. Kryptex’s coinbase in block 130,825 ends with 12 such bytes,
1550cad31e016e7bf00f2ecb, after its pool tag/pool.kryptex.com/.
| Field | Bytes | Value |
|---|---|---|
| Version version | 4 @0 | 2 int32 little-endian. Pearl wallets and pearld coinbases use version 1; relay policy accepts 1-2. |
| Marker marker | 1 @4 | 0x00 Segwit marker (BIP-144): says witness data follows the outputs. |
| Flag flag | 1 @5 | 0x01 Witness flag; 0x01 is the only value Pearl accepts. |
| Input count vin.length | 1 @6 | 1 CompactSize number of inputs. |
| Previous txid vin[0].txid | 32 @7 | 0000000000000000000000000000000000000000000000000000000000000000 All zeros: this input creates new coins (coinbase). |
| Output index vin[0].vout | 4 @39 | 0xffffffff 0xffffffff together with a zero txid marks a coinbase. |
| scriptSig length vin[0].scriptSig.length | 1 @43 | 39 CompactSize length of the scriptSig. |
| Coinbase script vin[0].scriptSig | 39 @44 | 0309ff01048393d76a2f706f6f6c2e6b7279707465782e636f6d2f1550cad31e016e7bf00f2ecb Coinbase data. It starts with the block height 130825 (BIP-34, required in every Pearl block), then anything the miner likes. |
| Sequence vin[0].sequence | 4 @83 | 0xffffffff Final (0xffffffff): no RBF signal, no relative locktime, and locktime is ignored for this input. Pearl wallets use this. |
| Output count vout.length | 1 @87 | 2 CompactSize number of outputs. |
| Amount vout[0].value | 8 @88 | 223,838,373,068 grains (2238.38373068 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains). |
| Script length vout[0].scriptPubKey.length | 1 @96 | 34 CompactSize length of the locking script. |
| Locking script vout[0].scriptPubKey | 34 @97 | prl1puv0gqv4x0wd0ylwz086y3sqrg4a6umza9r08aecehjrmdqq7mctsmqaqsh OP_1 OP_PUSHBYTES_32 <output key Q>: a Taproot output. |
| Amount vout[1].value | 8 @131 | 0 grains (0.00000000 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains). |
| Script length vout[1].scriptPubKey.length | 1 @139 | 38 CompactSize length of the locking script. |
| Locking script vout[1].scriptPubKey | 38 @140 | witness commitment 78cc1a61dcfcee9c59ddd9f4d56a98764c071e077bcc36fe9d1cf0aad50ebac3 OP_RETURN aa21a9ed ‖ SHA256d(witness Merkle root ‖ nonce): the BIP-141 witness commitment. |
| Witness items witness[0].length | 1 @178 | 1 Number of witness stack items for input 0. |
| Witness reserved value length witness[0][0].length | 1 @179 | 32 CompactSize length of this witness item. |
| Witness reserved value witness[0][0] | 32 @180 | 0000000000000000000000000000000000000000000000000000000000000000 The coinbase witness is one 32-byte value (the witness-commitment nonce); pearld uses zeros. |
| Locktime locktime | 4 @212 | 0 0: no time lock. |
Make a guess
A miner adds one more transaction to its template half-way through a multiplication. Can it keep the tickets it has already computed?
Think of your answer first, then check it.
Answer No.
The new transaction changes the Merkle root, so the first 76 header bytes change, so the job key, the noise seeds and the noise all change. Every ticket computed against the old template belongs to a block that is no longer being built. In practice miners pick up template changes between jobs, not mid-way.
Can a light wallet use Merkle proofs on Pearl?
It can, but it would only be trusting the header. Bitcoin’s old way for light wallets (BIP 37) sends a merkleblock: a header plus a Merkle proof for the wallet’s transactions. Pearl still has that message, but it carries the bare 108-byte header with no certificate, so a client relying on it alone couldn’t check that the block was really mined.
Pearl’s own light client works differently. It follows the compact-filter design (BIP 157/158), downloads every header with its certificate, and verifies each certificate’s zero-knowledge proof before trusting the chain. See light clients.
Code: the node's check
In checkBlockSanity (node/blockchain/validate.go:470-482 at v1.5.2, on GitHub), pearld builds the tree and
compares it with the header before anything else expensive:
calcMerkleRoot := CalcMerkleRoot(block.Transactions(), false)
if !header.MerkleRoot.IsEqual(&calcMerkleRoot) {
str := fmt.Sprintf("block merkle root is invalid - block "+
"header indicates %v, but calculated value is %v",
header.MerkleRoot, calcMerkleRoot)
return ruleError(ErrBadMerkleRoot, str)
} Then it rejects duplicate transactions (lines 484–496), and only after that verifies the certificate, because, as
the code comment says, “certificate verification is compute intensive”. The witness commitment is checked separately,
in checkBlockContext (node/blockchain/validate.go:762-766 at v1.5.2, on GitHub).