Reading — step 1 of 5
Read
Bitcoin Block Header
Time to stop simplifying. In this lesson your code reproduces the actual hash of the actual Bitcoin genesis block — the value 000000000019d668... that every full node on Earth agrees on. If a single byte of your serialization is off, you'll know immediately.
The header is exactly 80 bytes:
4 bytes version little-endian integer
32 bytes prev_block byte-REVERSED from the displayed hex
32 bytes merkle_root byte-REVERSED from the displayed hex
4 bytes timestamp little-endian (unix seconds)
4 bytes bits little-endian (compact difficulty target)
4 bytes nonce little-endian
Block hash = SHA-256(SHA-256(header)), then reverse the 32-byte digest for display. Double-SHA was Satoshi's belt-and-suspenders choice in 2008 (length-extension paranoia); Ethereum uses a single Keccak-256.
The endianness trap — the whole lesson in one sentence
Bitcoin serializes integers and hashes little-endian internally, but every explorer, RPC response, and human displays hashes big-endian — so you must byte-reverse the two hashes going in, and byte-reverse the digest coming out. Forget any one of the three reversals and you get a well-formed, useless hash. That bits field, for the curious, is a compact float-ish target encoding: 0x1d00ffff means 0x00ffff × 256^(0x1d − 3) ≈ 2^224 — the easiest target Bitcoin ever allowed, and the genesis hash's ten leading hex zeros are the proof-of-work sitting below it.
Genesis, for real
version = 1
prev = 0000...0000 (no parent)
merkle = 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
timestamp = 1231006505 (2009-01-03 18:15:05 UTC)
bits = 486604799 (0x1d00ffff)
nonce = 2083236893
hash = 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
Its coinbase embeds "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks."
The idiom
Note .digest() on the inner hash, not .hexdigest(): the second SHA-256 must eat the raw 32 bytes. Hashing the 64-character hex string of the first digest is the single most common bug in this exercise — it types-checks, runs, and produces garbage.
Your exercise
Each line gives <version>|<prev_hex>|<merkle_hex>|<timestamp>|<bits>|<nonce> (hashes in display order); print the display-order block hash. Test 0 is the genesis block above and must print exactly 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f; tests 1–2 are real Bitcoin blocks 1 and 2. The grader catches, in descending order of popularity: double-hashing the hex string instead of raw bytes, skipping the [::-1] on prev/merkle (the leading zeros vanish), and forgetting the final digest reversal (your zeros come out trailing). Get all three reversals and both raw-byte hashes right, and three real mainnet hashes fall out of your code — enjoy that moment.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…