Learning LibraryBlockchain & DeFi LibraryTeens

Blocks and chains: linking data by hash

A blockchain's magic is in the links. Each block carries the hash of the one before it, so the blocks form a chain where changing any link is instantly detectable.

The big idea

Each block stores the previous block's hash, chaining them so that altering one block changes every hash that follows.

See it in code

1The basics

A block's hash is computed from two things: the data inside it and the prev — the hash of the block before. The very first block (the genesis block) has no real predecessor, so its prev is just zeros:

python
import hashlib

def sha(text):
    return hashlib.sha256(text.encode()).hexdigest()

prev = "0" * 8
data = "Genesis"
h = sha(prev + data)[:8]
print(f"{data} | prev={prev} -> hash={h}")
Run it — one block, its hash built from prev + data:
Genesis | prev=00000000 -> hash=cf0cb18a

This block's fingerprint, cf0cb18a, folds in both its data and its prev. The next block will carry this hash as its own prev — that's the link.

2A step further

Add a second block whose prev is the genesis block's hash. Now block 2 literally contains a fingerprint of block 1 — the two are welded together:

python
import hashlib

def sha(text):
    return hashlib.sha256(text.encode()).hexdigest()

h1 = sha("00000000" + "Genesis")[:8]
h2 = sha(h1 + "Alice pays Bob")[:8]

print("Block 1 hash:", h1)
print(f"Block 2 | prev={h1} -> hash={h2}")
Run it — block 2's prev is exactly block 1's hash:
Block 1 hash: cf0cb18a
Block 2 | prev=cf0cb18a -> hash=ac3d690e

Block 2's prev is block 1's hash — cf0cb18a in both. Chain a third block the same way and you have the pattern below.

3In our world

A loop scales that link to any length. Each block's hash is computed from the previous hash plus its own data, and that hash becomes the prev for the next — three blocks, one rule:

python
import hashlib

def sha(text):
    return hashlib.sha256(text.encode()).hexdigest()

blocks = ["Genesis", "Alice pays Bob", "Bob pays Carol"]
prev = "0" * 8
for data in blocks:
    h = sha(prev + data)[:8]
    print(f"{data} | prev={prev} -> hash={h}")
    prev = h
Run it — each block's hash feeds into the next:
Genesis | prev=00000000 -> hash=cf0cb18a
Alice pays Bob | prev=cf0cb18a -> hash=ac3d690e
Bob pays Carol | prev=ac3d690e -> hash=befd3972

See how each block's prev equals the block before it's hash? The genesis and Alice hashes match the two blocks we built by hand above — that's the chain. If someone edited the 'Alice pays Bob' block, its hash would change, so the next block's stored prev wouldn't match — and the tampering would be obvious to everyone.

The same idea, everywhere

Linking each item to a fingerprint of the previous one makes a tamper-evident log. Git commits chain this exact way (each commit references its parent's hash), as do secure audit trails and version histories. Chaining by hash turns a list into something you can't quietly rewrite.

Try it yourself

Change the text of the middle block and recompute — watch its hash, and every hash after it, change. Then store the blocks in a list of dictionaries and write a verify() that checks each prev matches.

The common mistake

Thinking you can edit one block in isolation. Because every later block's hash depends on it, changing block 1 invalidates 2, 3, and all the rest. That cascade is the whole security idea — one edit, and the chain visibly breaks.

What it unlocks

Chaining by hash is the core of what a blockchain is, builds on hashing, and is secured by proof of work.