用 Python 亲手搭建一条迷你区块链:零基础也能跑的加密货币 Demo

·

关键词:Python 区块链、加密货币、工作量证明、哈希、创世区块、节点、共识机制、挖矿、数据结构

从 HashCat 到门头沟事件,你一定听过“区块链”这个词。与其遥遥观望,不如亲自写代码跑出一条「最小可行区块链」(Minimum Viable Blockchain)。本文将通过 Python 3.9+ 为媒介,演示如何用最直觉的代码建起一条含 创世区块、工作量证明、简易节点网络 的最简加密货币原型。全部代码不超过 150 行,任何操作系统均可一键运行。

01 预备知识与环境清单

依赖最低版本安装方法
Python3.9.4官网 下载安装
本机网络默认面向单机跑通即可
代码编辑器任意VS Code / PyCharm / Notepad++ 均可

打开命令行,确认版本:

python --version
# Python 3.9.4 或更高

02 项目结构速览

crypto_demo/
│
├── app.py       # 主文件,区块链 & 加密货币逻辑全部写这
└── README.md    # (可选)记录你的实验笔记

03 创建 Block 类:承载交易数据的最小单元

区块(Block)是整条链的“原子”。一个区块包含 5 个关键字段:

代码如下:

import hashlib, time

class Block:
    def __init__(self, index, proof_number, previous_hash, data, timestamp=None):
        self.index = index
        self.proof_number = proof_number
        self.previous_hash = previous_hash
        self.data = data
        self.timestamp = timestamp or time.time()

    @property
    def compute_hash(self):
        """把每个字段拼成字符串后哈希"""
        block_string = f"{self.index}{self.proof_number}{self.previous_hash}{self.data}{self.timestamp}"
        return hashlib.sha256(block_string.encode()).hexdigest()

❓FAQ 1:为什么用 SHA256?

因为它足够年轻且简洁,一段 256 位的二进制输出即能代表“指纹”,碰撞概率趋近零。任何微小改动哈希值都会面目全非,防篡改就靠它。

04 Blockchain 类:聚合区块的“主链”思维

4.1 核心成员变量

变量作用
chain存储已确认区块的有序列表
current_data暂存尚未打包进区块的交易集合
nodes未来做分布时记录的节点集合

4.2 构建创世区块

任何链都得从“第 0 号”开始,称为 创世区块(Genesis Block)。创世区块的 previous_hash 固定记为 0proof_number 通常设 0。

class Blockchain:
    def __init__(self):
        self.chain = []
        self.current_data = []
        self.nodes = set()
        self.build_genesis()

    def build_genesis(self):
        self.build_block(proof_number=0, previous_hash="0")

    def build_block(self, proof_number, previous_hash):
        block = Block(
            index=len(self.chain),
            proof_number=proof_number,
            previous_hash=previous_hash,
            data=self.current_data
        )
        self.current_data = []  # 清空队列,准备下一批交易
        self.chain.append(block)
        return block

❓FAQ 2:为什么要“清空队列”?

区块链网络同一时间只能有一条最长链。当新区块被确认后,所有尚未上链的交易理论上已失效;我们简单演示,所以直接丢弃等待再次写入即可。

05 实现 PoW:工作量的“无聊”算力

工作量证明(Proof-of-Work)是比特币的安全基石,其本质是让计算机做“不容易算、却极易验证”的哈希算术题,下面给出极简版:

@staticmethod
def proof_of_work(last_proof):
    """找一个数 x 使得 hash(last_proof||x) 前 4 位为 0"""
    x = 0
    while True:
        guess_hash = hashlib.sha256(f"{last_proof}{x}".encode()).hexdigest()
        if guess_hash[:4] == "0000":
            return x
        x += 1

4 位前缀的零越短,挖矿越轻松;反之上百上千台 GPU 挖一晚上也拿不到。👉 想亲手调参感受算力惩罚,可前往交互式沙盒

06 简易交易:记录链上转账

get_data 抽象成对外接口,向 current_data 追加「发送方 → 接收方」的转移记录:

def get_data(self, sender, receiver, amount):
    self.current_data.append(
        {"sender": sender, "receiver": receiver, "amount": amount}
    )
    return True

严格来说,它还应该验证交易双方余额、防止双重支付,但本文聚焦“跑通”而非商业级功能。

07 验证区块合法性

每条链都需要自检“螺丝松动”。我们通过静态方法实现:

@staticmethod
def confirm_validity(block, prev_block):
    return (
        prev_block.index + 1 == block.index and
        prev_block.compute_hash == block.previous_hash and
        block.timestamp > prev_block.timestamp
    )

❓FAQ 3:时间戳为何必须递增?

链是时间顺序,过去(较低索引)记录的交易不能晚于未来(较高索引)。保证不可变的次序一致性。

08 挖矿同步:把大量算力压缩成一行代码

把复杂逻辑包装成对外友好的“挖矿 API”:

def block_mining(self, miner_addr):
    self.get_data(sender="0", receiver=miner_addr, amount=1)  # 矿工奖励
    last_block = self.latest_block
    last_proof = last_block.proof_number
    proof = self.proof_of_work(last_proof)
    last_hash = last_block.compute_hash
    new_block = self.build_block(proof, last_hash)
    return new_block

@property
def latest_block(self):
    return self.chain[-1]

恭喜!你已拥有可挖出的最小币种——不妨起名“PyCoin”。👉 把代码一键部署在云端试听运行效果

09 运行测试:见证“第一条链”的诞生

app.py 末尾加入以下片段,保存后执行 python app.py

if __name__ == "__main__":
    chain = Blockchain()
    print("=== 创世完成 ===")
    print(f"链长:{len(chain.chain)},区块哈希:{chain.latest_block.compute_hash}")

    # 发几笔交易
    chain.get_data("Alice", "Bob", 5)
    chain.get_data("Bob", "Charlie", 2)

    # 挖矿
    chain.block_mining("Dave")
    print(f"成功挖出新区块,链长度:{len(chain.chain)}")

    # 验证
    for b in chain.chain:
        print(vars(b))

输出示例:

=== 创世完成 ===
链长:1,区块哈希:d9b1b...
成功挖出新区块,链长度:2
{'index': 0, 'proof_number': 0, 'previous_hash': '0', ...}
{'index': 1, 'proof_number': 533, 'previous_hash': 'd9b1b...', ...}

10 如何继续演化这条链

❓FAQ 4:加密货币能上线交易所吗?

理论上,只要你创建足够完整的开源项目、智能合约及白皮书,可申请上币;但实际评估生产安全、性能、合规及社区,远超本文范围。

❓FAQ 5:PoW 太耗能怎么办?

可改用 PoS(权益证明)PoA(权威证明),在私有/联盟链中效果尤佳,Python 同样能用 pyethappweb3.py 插件快速切换。

❓FAQ 6:代码能直接用于主网吗?

不能!当前仅是单机 Demo,未含 UTXO、账户模型、GAS、EVM 等底层要素。要跑主网,需迁移到成熟框架如 Golang+Tendermint 或 Rust+Substrate。


恭喜你读完 1500+ 字,手里的「PyCoin」已初具雏形。欢迎把代码分享到 GitHub 并 @ 我,你的每个 Merge 都是区块链自学旅程最闪亮的标志!