Reading — step 1 of 5
Read
Block Structure
Strip away the hype and a blockchain is a modest data structure: a linked list where the "pointer" is a cryptographic hash. Each block carries the hash of its predecessor, so every block commits to the entire history behind it.
Block N Block N+1
prev_hash: H(block N-1) prev_hash: H(block N) <-- links back
timestamp: when created ...
merkle_root: summary of txs
nonce: free field (PoW)
transactions...
Change one byte anywhere in block N and H(block N) changes, so block N+1's prev_hash no longer matches, so block N+1's own hash changes, and the mismatch cascades to the tip.
What immutability actually means (and doesn't)
Be precise here, because this is the most misquoted idea in the field. A hash chain by itself is tamper-evident, not tamper-proof. Recomputing a SHA-256 hash takes microseconds — if you control the data, you can rewrite block N and re-link every successor faster than you can read this sentence. Two additions turn "evident" into "expensive":
- Proof of Work (later lesson): each re-linked block must also satisfy a difficulty target, so rewriting N blocks costs N blocks' worth of mining.
- Replication: thousands of nodes hold copies and reject a history that contradicts the one they validated.
Git uses exactly the same hash-chain trick (every commit hashes its parent) with neither addition — and indeed Git history is rewritable by anyone with push access. The chain structure gives you detection; economics and distribution give you resistance.
The real header
Bitcoin's block header is exactly 80 bytes: version (4), prev_block_hash (32), merkle_root (32), timestamp (4), difficulty bits (4), nonce (4). On the wire all fields are serialized little-endian; explorers display the hashes byte-reversed (a later lesson makes you do this for real). The block hash is SHA-256(SHA-256(header)) — double-SHA is a Bitcoin quirk; Ethereum uses Keccak-256, single pass. Note what's not hashed directly: transactions enter only through the 32-byte merkle_root, which is why the header can stay fixed-size no matter how many transactions the block holds.
The idiom — and the trap
This course simplifies the header to a pipe-joined string and a single SHA-256:
The trap is doing more than asked. The input line is the preimage. If you split the fields and rebuild the string, you invite three bugs: dropping the pipes (prev + merkle + ts + nonce hashes differently than prev|merkle|ts|nonce), collapsing empty fields (ff||0|0 has an empty merkle_root that must stay as two adjacent pipes), and parsing fields as integers (one test feeds a|b|c|d — the "timestamp" is the letter c; int() crashes). Hash bytes, exactly as given, lowercase hex out.
Your exercise
Read lines of <prev_hash>|<merkle_root>|<timestamp>|<nonce> and print the 64-char SHA-256 hex of each full line. The first test hashes the all-zero prev_hash line and must print exactly 2486333ec43d7952bdfb5bac2560d38984625722b5daecdb9c829aff7bf1cec4. The grader's favorite catch: students who double-SHA (Bitcoin habit) or hash the concatenated fields without the | separators — both produce a perfectly valid-looking 64-char hash that matches nothing. Single SHA-256, whole line, pipes included.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…