§ 07 · Blocks
Previous block
The 32 bytes that turn a pile of blocks into a chain
On this page 7 sections
Every block points back at the block before it. The pointer is the parent’s block hashBlock hash: A block's ID: the double SHA-256 of its 108-byte header. On Pearl it looks random, because it is never compared with the target., written into the second field of the header.
That’s the whole trick behind a blockchain. Each block names its parent by a fingerprint of the parent’s header. The parent names its own parent, and so on, all the way back to the genesis blockGenesis block: Block 0, written into the software rather than mined. Pearl's is dated 27 April 2026, pays no reward, and quotes a Bitcoin block hash to show it wasn't made earlier.. Change any old block and its fingerprint changes, and every link after it breaks.
Try it
Edit a block in the middle of a short chain and watch every later block turn invalid.
What does it look like?
- Size
- 32 bytes
- Type
- SHA256d hash of the parent's header
- 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 4 to 35 of block 130,827’s header are:
999c961b04d94b8b21134e862dc31d5fa56cf9d1f027adb2a0cf95c6525c55eb Reverse them byte by byte and you get the hash of block 130,826, as any explorer shows it:
eb555c52c695cfa0b2ad27f0d1f96ca55f1dc32d864e13218b4bd9041b969c99
Why is it stored backwards?
It isn’t, quite. A hash comes out of SHA-256 as 32 bytes in a fixed order, and that’s the order the header stores. This is the internal byte order.
When Bitcoin’s software prints a hash, it reverses the bytes, treating the hash as one big little-endianLittle-endian: Storing a number that spans several bytes with its smallest byte first. Pearl, like Bitcoin, stores numbers this way, and shows hashes with their bytes reversed. number written the usual way, biggest digit first. Pearl inherited that habit unchanged, so every block hash and transaction ID you see on an explorer is the reverse of the bytes on the wire. See byte order.
Going deeper A habit that lost its reason
In Bitcoin, reading the hash as a little-endian number is what the proof-of-work check does, so the reversed display puts a winning hash’s zeros at the front where people can see them. Pearl never compares the block hash with the target, so its block hashes have no leading zeros to show. The reversal is now pure convention.
Where does the chain start?
At genesis, which has no parent. Its previous-block field is 32 zero bytes.
Block 1 is the first real link. Its previous-block field holds the genesis hash, 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. |
| Bytes in block 1’s header | Displayed | |
|---|---|---|
| Previous block | d7ad8dc5…93308da1 |
a18d3093b7ff618f0cdd073fa3d10374e2e0105fe7ef53ff48b55f41c58dadd7, the genesis hash |
What does the link protect?
Everything before it. Here is the chain of consequences if someone edits one transaction in an old block:
-
The old block's Merkle root changes
The transaction’s ID changes, so the Merkle root in that block’s header changes.
-
So its block hash changes
The block hash is SHA256d of all 108 header bytes, Merkle root included.
-
So the next block's link is broken
The next block’s previous-block field still holds the old hash. To fix it, that header must change too, which changes its hash, which breaks the block after it.
-
So every later block needs new mining work
Each rewritten header needs a valid certificate, and a certificate is bound to its header’s first 76 bytes, previous block included. The attacker must redo the mining work of every block up to the tip, faster than the honest network adds new ones.
On Pearl the links cover more than in Bitcoin. A Pearl header ends with a proof commitment, a hash of the certificate’s public data. So the chain of block hashes also chains every winning ticket since genesis.
Can a block’s parent be any block?
The parent must be a block the node already knows, and the new block’s heightBlock height: A block's position in the chain, counting from the genesis block at height 0. is the parent’s plus one. Two blocks can share a parent; that’s a fork, and nodes follow the chain with the most work, as in Bitcoin, with one Pearl twist (a switch needs a small extra margin of work). See the most-work chain.
Pearl’s nodes also carry checkpointsCheckpoint: A block hash built into the node software at a fixed height. Pearl has one every 10,000 blocks so far, and nodes refuse any chain that disagrees with them., one every 10,000 blocks, and refuse any fork that branches off below the latest one (block 120,000 in v1.5.2).
Why does mining care about the parent?
Because the previous block is part of the mining puzzle itself. A Pearl miner hashes the first 76 bytes of its block template (version, previous block, Merkle root, time and bits) together with its mining settings into a 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.. All the puzzle’s randomness flows from that key: the noise seedsNoise seed: One of two random-looking values made from the job key and fingerprints of the two matrices (and, since block 99,000, their sizes). Each seed grows into one noise matrix., the noise, and therefore every lottery ticket. See noise seeds.
Make a guess
A new block arrives while your GPU is half-way through a huge multiplication for the next one. What happens to the work done so far?
Think of your answer first, then check it.
Answer It's thrown away.
The new block becomes your new parent. Your template’s previous-block field changes, so the job key changes, so the noise changes, so every ticket you’d produce from here on is different. Tickets already checked against the old template can’t be moved over. Mining restarts on the new tip, just as a Bitcoin miner restarts its nonce search.
Code: the field, and how it reaches the prover
The field is PrevBlock chainhash.Hash in
BlockHeader (node/wire/blockheader.go:21-41 at v1.5.2, on GitHub), written as raw bytes. Printing a hash reverses
it, in Hash.String() (node/chaincfg/chainhash/hash.go:73-80 at v1.5.2, on GitHub):
func (hash Hash) String() string {
for i := 0; i < HashSize/2; i++ {
hash[i], hash[HashSize-1-i] = hash[HashSize-1-i], hash[i]
}
return hex.EncodeToString(hash[:])
} When a node verifies a certificate, it hands the Rust verifier its own copy of the first five fields, in
blockHeaderToC (node/zkpow/verify.go:222-238 at v1.5.2, on GitHub). The copy holds the two hashes in display order,
and the Rust side reverses them back when it serializes, so the job key hashes exactly the header’s first 76 bytes. A
certificate made for one parent fails against any other.