How to Build a Blockchain in Python: Step-by-Step Guide
A blockchain is a chain of blocks linked by cryptographic hashes: each block contains data, a timestamp, and the hash of the block before it, which makes tampering with history computationally obvious. The best way to understand that is to build one, and Python's standard library has everything required. This guide builds a working blockchain from scratch: blocks, hashing, proof of work, and validation, in about 60 lines of real code.
How a blockchain works, in one paragraph
Every block stores its predecessor's hash. Change any historical block and its hash changes, which breaks every block after it, so fraud requires re-mining the entire chain faster than the honest network extends it. Add a consensus rule (here, proof of work) and you have the tamper-resistant, decentralized ledger that powers cryptocurrencies, supply-chain tracking, and smart contracts.
Step 1: Define the block
A block needs an index, a timestamp, its data, the previous block's hash, a nonce for mining, and its own hash computed from all of the above:
import hashlib
import json
import time
class Block:
def __init__(self, index, data, previous_hash):
self.index = index
self.timestamp = time.time()
self.data = data
self.previous_hash = previous_hash
self.nonce = 0
self.hash = self.compute_hash()
def compute_hash(self):
payload = json.dumps({
"index": self.index,
"timestamp": self.timestamp,
"data": self.data,
"previous_hash": self.previous_hash,
"nonce": self.nonce,
}, sort_keys=True)
return hashlib.sha256(payload.encode()).hexdigest()SHA-256 turns the block's contents into a fixed-length fingerprint; any change to any field produces a completely different hash.
Step 2: Build the chain with a genesis block
class Blockchain:
difficulty = 4 # leading zeros required by proof of work
def __init__(self):
self.chain = [self.create_genesis_block()]
def create_genesis_block(self):
return Block(0, "Genesis Block", "0")
@property
def last_block(self):
return self.chain[-1]The genesis block is the only block without a real predecessor; every other block chains back to it.
Step 3: Add proof of work
Proof of work makes adding blocks expensive: miners increment the nonce until the hash starts with `difficulty` zeros. Verifying costs one hash; forging costs millions.
def proof_of_work(self, block):
block.nonce = 0
computed = block.compute_hash()
while not computed.startswith("0" * self.difficulty):
block.nonce += 1
computed = block.compute_hash()
return computed
def add_block(self, data):
block = Block(
index=self.last_block.index + 1,
data=data,
previous_hash=self.last_block.hash,
)
block.hash = self.proof_of_work(block)
self.chain.append(block)
return blockStep 4: Validate the chain
Validation walks the chain checking two things: every block's hash is genuine, and every block points at its predecessor's real hash.
def is_valid(self):
for i in range(1, len(self.chain)):
current, previous = self.chain[i], self.chain[i - 1]
if current.hash != current.compute_hash():
return False
if current.previous_hash != previous.hash:
return False
return TrueStep 5: Run it
chain = Blockchain()
chain.add_block({"from": "alice", "to": "bob", "amount": 5})
chain.add_block({"from": "bob", "to": "carol", "amount": 2})
print(f"Chain valid: {chain.is_valid()}") # True
chain.chain[1].data = {"from": "alice", "to": "mallory", "amount": 500}
print(f"After tampering: {chain.is_valid()}") # FalseThat last line is the entire point of blockchain, demonstrated: history rewritten is history detected.
Where to go from here
A production blockchain adds peer-to-peer networking (nodes broadcasting blocks), a consensus rule for competing chains (longest valid chain wins), transaction signing with public-key cryptography, and usually an HTTP API (Flask or FastAPI make that step natural in Python; our guide to Python app development covers those frameworks). For smart-contract platforms, you would instead build on existing chains with web3.py rather than from scratch.
Should you actually use blockchain?
Honest answer: only when you need shared, tamper-evident state among parties who do not trust each other, such as cryptocurrencies, cross-organization supply chains, and decentralized finance. If one database owner is acceptable, a database is simpler, faster, and cheaper. When the use case is real, though, the engineering gets serious quickly, which is what our blockchain development team handles at production scale, including builds like this high-performance on-chain perpetual DEX.
Frequently asked questions
Can you build a real blockchain in Python?
Yes for learning, prototyping, and permissioned systems; Python's clarity makes it the best teaching language for the concepts. Public high-throughput chains typically use Rust, Go, or C++ for performance, with Python serving tooling and integration.
How long does it take to build a blockchain?
The educational version above: an afternoon. A production system with networking, consensus, and signing: months, which is why most real projects build on existing platforms like Ethereum rather than from scratch.
What Python libraries are used for blockchain?
`hashlib` and `json` from the standard library cover the fundamentals; `web3.py` connects Python to Ethereum for real decentralized applications, and Flask or FastAPI expose your chain as an API.
The bottom line
Sixty lines of Python demystify the technology behind a trillion-dollar asset class: hashes chain the blocks, proof of work makes rewriting history expensive, and validation makes tampering visible. Build the toy to understand the real thing, then decide with clear eyes whether your problem truly needs one. When it does, our blockchain developers build the production version.
Blockchain engineering beyond the tutorial
From smart contracts to full on-chain platforms, Coding Crafts builds production blockchain systems with senior engineers at $25 to $49 per hour.
More from the journal.
View all postsRelated reading from the Coding Crafts team.
