Skip to content
Block Structure
step 1/5

Reading — step 1 of 5

Read

~3 min readBlocks & Hashing

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":

  1. 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.
  2. 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:

python

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…