Open this lesson in your favourite AI. It'll walk you through the why, explain the demo, and quiz you on the try-it list.
Bitcoin's block header is just 80 bytes — the smallest possible commitment to a block's contents. Light clients (BIP-37, BIP-157) rely on header-only sync for security. Knowing the header layout precisely is essential for any wallet, indexer, or compact-client work.
Block header anatomy.
Use these three in order. Each builds on the one before.
In one paragraph, explain a Bitcoin block header.
Walk me through merkle proof verification for a light client.
Design a compact-block-relay protocol that minimizes bandwidth for new blocks while preserving security.
pub struct BlockHeader {
pub version: i32, // 4 bytes
pub prev_block_hash: [u8; 32], // 32 bytes — links to parent
pub merkle_root: [u8; 32], // 32 bytes — commits to all tx in block
pub time: u32, // 4 bytes — unix timestamp
pub bits: u32, // 4 bytes — encoded difficulty target
pub nonce: u32, // 4 bytes — miners adjust to find valid hash
}
// Total: 80 bytes
// Block hash = sha256(sha256(serialize(header)))
// Must be < target (decoded from bits) for the block to be valid.
pub fn block_hash(h: &BlockHeader) -> [u8; 32] {
let mut buf = Vec::with_capacity(80);
buf.extend(&h.version.to_le_bytes());
buf.extend(&h.prev_block_hash);
buf.extend(&h.merkle_root);
buf.extend(&h.time.to_le_bytes());
buf.extend(&h.bits.to_le_bytes());
buf.extend(&h.nonce.to_le_bytes());
sha256(&sha256(&buf))
}
// Merkle root commits to every transaction in the block — a 32-byte
// summary that lets light clients verify a tx is included with O(log n)
// hashes via a merkle proof.
// Bits encoding is compact: an 8-bit exponent + 24-bit mantissa.
// target = mantissa * 256^(exponent - 3)
// Block 100000 had bits 0x1b04864c -> target ~5.7e62 (very easy by today's standards)