如果让我从自己的实践里推荐一个能把 Python 类、哈希算法、数据结构甚至 Web 接口全部串起来的练手项目,我会选“用 Python 从零写一个极简区块链”。先别被名字吓到,我对朋友做白话解释时特别简单:它就是一个不允许轻易改动的账本,账本的每一页都带着前一页的“指纹”,任何一页被涂改,后面所有页都会对不上。这篇文章我会带着你从空文件开始,写出一个能挖矿、能记账、能校验、并且能被浏览器查询的小型区块链。整个核心实现只依赖 Python 标准库,也完全不涉及真实货币和网络;重点是把区块、哈希、工作量证明这些概念一个个拆开揉碎。适合有基础 Python 语法、想真正理解区块链底层逻辑的人,哪怕是准备技术面试,你也可以用这段代码把共识和防篡改讲得明明白白。
在正式写代码前,先花点篇幅把设计讲清楚,带着这张图开始,后面动手会顺畅很多。
1. 项目整体设计与思路拆解
1.1 区块链大白话:什么是“链”上的区块
我曾试过用一句话向完全没接触过的人解释区块链,最有效的是把它想成“一本每一页都印着前一页防伪码的财务账本”。账本的每一页叫“区块”,里面记录若干条交易信息。每一页除了记录交易,还会印上一个由本页所有内容计算的哈希值,这串哈希可以理解成该页的唯一防伪码。这本账本的特别之处在于,每一页还会把上一页的防伪码抄到自己页面上。所以如果某人想把第 3 页的交易从 100 元改成 999 元,第 3 页的哈希立刻改变,而第 4 页上记录的还是第 3 页原来的哈希,两者就对不上了。想继续伪造,他必须把从第 4 页开始的所有页面全部重写,并且每一页都要做一次很费劲的“找哈希”计算。正是因为重写整本账的成本极高,才让链上的历史数据变得难以篡改。
刚才提到的“很费劲的找哈希”,就是常说的工作量证明 PoW。真实区块链中矿工做的事情,本质上就是对新页面找一个随机数,让新页面的哈希满足一定条件,例如“前 4 个字符必须是 0”。这个条件没有聪明解法,只能拿不同的 nonce 值一遍遍试哈希。哈希函数像一台单向搅拌机,输入稍微变化,输出就会完全不一样;
1.2 为什么用 Python 来手写区块链
这个项目选择 Python,核心是四个字:开发效率。区块链技术本身有大量抽象概念,而 Python 的类、字典、列表能非常直观地对应上区块、交易、节点等结构。在验证共识、链完整性、Web 接口这些功能时,Python 几十行代码就能搭出原型,这对理解原理特别有帮助。如果一上来就使用复杂的 C++、Go 或者 Rust,很多精力会消耗在内存管理、模块组织等基础设施上,反而不利于抓住核心。
技术选型方面,做核心区块和链的部分,只需要三个标准库:hashlib 计算 SHA-256 哈希、json 做区块数据的序列化、time 记录时间戳。如果你希望把链发布到浏览器里查看,可以额外装一个轻量级的 Flask,仅仅是为了提供 HTTP 接口。整套代码的“正确最小依赖”其实比很多人想象中少,这也从侧面证明区块链底层的“账本结构”并没有那么高不可攀。
我在设计时坚持把代码分成四块:
Block类:负责定义区块字段,计算当前区块哈希。Blockchain类:负责维护整条链、创建创世区块、追加新区块。- 工作量证明函数:负责给区块寻找满足难度的 nonce 值。
- Web 展示层:把区块数据通过 JSON API 暴露给浏览器或命令行,主要是为了验证和观察。
这样拆分后,哪怕你只想理解其中某个模块,也不用被几百行代码绕晕。
1.3 动手前先检查 Python 环境
写和运行代码前,最好先确认你的机器上有可用的 Python 环境。我自己在 Windows、macOS、Linux 都跑过,只要是 Python 3.8 以上版本,核心代码基本不需要额外安装依赖。
先打开终端或命令提示符,执行:
bash复制python --version
如果没有正确输出版本,说明你可能还没把 Python 加入环境变量。Windows 安装比较简单,去 Python 官网下载对应安装包,安装时务必勾选“Add Python to PATH”,这是初学者最容易忽略的一步,勾不勾会直接影响后续能否在命令行里直接使用 python 命令。
如果你使用 VSCode 开发,我建议做两件事:第一,安装官方 Python 扩展;第二,在项目目录里创建一个虚拟环境,避免把不同项目的依赖混在一起。
bash复制python -m venv venv
Windows 下激活虚拟环境的命令是:
bash复制venv\Scripts\activate
macOS 或 Linux 下是:
bash复制source venv/bin/activate
激活后命令行前面会出现 (venv) 字样,再执行 python 就走的虚拟环境。如果在 Web 演示部分需要 Flask,再执行:
bash复制pip install flask
看到这里,环境已经就绪。接下来进入最核心的部分,先从区块的数据结构和哈希计算说起。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心原理与实现细节:区块、哈希与工作量证明
2.1 区块结构设计:先明确一个区块里放什么
我在自己第一次写区块链代码时,犯过“把功能堆在一起”的毛病。后来琢磨清楚,区块对象其实只需要几个关键字段就够了:
index 是区块高度,从 0 开始递增,方便确认顺序;
timestamp 是区块生成时间;
transactions 是交易列表,在这里用 Python 字典来模拟;
previous_hash 是上一个区块的哈希值,这是形成“链”的核心;
nonce 是挖矿时用于暴力尝试的随机数;
hash 是当前区块自己的哈希值。
计算哈希时,我想强调一个容易踩坑的点:区块中存放的 hash 字段本身不应该参与自身的哈希计算,否则你会陷入“自己包含自己”的循环。正确做法是,把除 hash 以外的字段,按照固定顺序序列化,再用 SHA-256 计算摘要。我习惯用 sort_keys=True 对字典键排序,并用 separators=(",", ":") 去掉多余空格,这样保证同一份逻辑在任何平台、任何时候计算出来的结果都一致。
下面是基础版区块类的代码:
python复制import hashlib
import json
import time
class Block:
def __init__(self, index, transactions, previous_hash, nonce=0):
self.index = index
self.timestamp = time.time()
self.transactions = transactions
self.previous_hash = previous_hash
self.nonce = nonce
self.hash = self.compute_hash()
def compute_hash(self):
block_string = json.dumps({
"index": self.index,
"timestamp": self.timestamp,
"transactions": self.transactions,
"previous_hash": self.previous
