Python 区块链手把手教程:从零亲手打造一条链

·

区块链概念火爆多年,仍被不少开发者视为“高深”. 如果你钟爱 Python 的高可读性,却又想亲手体验「造链」魅力,这篇教程正是为你量身定制。我们将用最接地气的语言,带你用 Python 区块链 的原生代码,一砖一瓦搭建一条可运行、可扩展的 去中心化账本

阅读完本文,你无需外部框架,即可理解 区块链架构、共识算法、交易验证、链安全 等核心技术;同时,还能 fork 源码继续迭代,应用在 加密资产、供应链金融、智能合约原型 等场景。


为什么要用 Python 做区块链?

关键词稀疏嵌入:区块链开发、Python 区块链、私有链、智能合约原型、去中心化账本、数字签名、共识算法。


动手之前:明确业务场景

很多初学者一上来就写代码,结果越写越迷茫。请先回答下面三个问题:

  1. 你想解决什么痛点?是 防止数据篡改,还是 降低中介成本
  2. 是否必须去中心化?某些高并发、隐私性强的场景,传统数据库+审计日志更划算。
  3. Token 是否必须发行?无币链(Hyperledger Fabric 思路)也能达成多方共识。

👉 用5分钟评估区块链方案的5个实用画布,点击即可体验


运行环境准备(5 分钟版)

打开终端,验证版本:

python3 --version  # Python 3.11.x
python3 -c "import hashlib, json, time, threading; print('OK')"

架构剖析:一条最小区块链长什么样?

  1. Block 结构

    • index:块高度
    • timestamp:出块时间
    • transactions:交易列表
    • previous_hash:父块指纹
    • nonce:工作量证明随机数
    • hash:当前块指纹
  2. 链式结构

    • 所有区块以 previous_hash 相连,形成单向链表。
    • 若任一节点修改历史交易,后续所有哈希都会变,链立即断裂。
  3. 共识算法
    本教程用 PoW(Proof of Work) 作为入门;后续可自行升级 PoS(Proof of Stake)BFT

Step 1:创建 Block 类

import hashlib, json, time
from typing import List, Dict, Any

class Block:
    def __init__(self, index: int, transactions: List[Dict[str, Any]],
                 previous_hash: str, timestamp: float = None, nonce: int = 0):
        self.index = index
        self.transactions = transactions
        self.previous_hash = previous_hash
        self.timestamp = timestamp or time.time()
        self.nonce = nonce
        self.hash = self.calculate_hash()

    def calculate_hash(self) -> str:
        block_string = json.dumps({
            "index": self.index,
            "transactions": self.transactions,
            "previous_hash": self.previous_hash,
            "timestamp": self.timestamp,
            "nonce": self.nonce
        }, sort_keys=True)
        return hashlib.sha256(block_string.encode()).hexdigest()

    def mine_block(self, difficulty: int = 4):
        prefix = '0' * difficulty
        while not self.hash.startswith(prefix):
            self.nonce += 1
            self.hash = self.calculate_hash()

Step 2:创建 Blockchain 类

封装链的操作:添加交易、打包出块、验证有效性。

class Blockchain:
    def __init__(self):
        self.chain = [self.create_genesis_block()]
        self.difficulty = 4
        self.pending_transactions = []
        self.mining_reward = 1

    def create_genesis_block(self) -> Block:
        return Block(0, [], "0")

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

    def add_transaction(self, sender: str, recipient: str, amount: float):
        self.pending_transactions.append({
            "sender": sender,
            "recipient": recipient,
            "amount": amount
        })

    def mine_pending_transactions(self, miner_address: str):
        self.pending_transactions.append({
            "sender": "network",
            "recipient": miner_address,
            "amount": self.mining_reward
        })
        new_block = Block(len(self.chain), self.pending_transactions,
                          self.latest_block.hash)
        new_block.mine_block(self.difficulty)
        self.chain.append(new_block)
        self.pending_transactions = []

    def is_chain_valid(self) -> bool:
        for i in range(1, len(self.chain)):
            current = self.chain[i]
            previous = self.chain[i-1]
            if current.hash != current.calculate_hash():
                return False
            if current.previous_hash != previous.hash:
                return False
        return True

Step 3:用 REPL 体验交互式 Demo

if __name__ == "__main__":
    my_chain = Blockchain()
    # 用户 Alice 给 Bob 转账 50
    my_chain.add_transaction("Alice", "Bob", 50)
    # 矿工是 Charlie
    my_chain.mine_pending_transactions("Charlie")

    print("链是否有效?", my_chain.is_chain_valid())
    for b in my_chain.chain:
        print(b.__dict__)

运行结果会显示两个区块:创世块 + Alice→Bob 转账块,外加 mining_reward 交易。


单元测试:守护链安全

import unittest

class TestBlockchain(unittest.TestCase):
    def test_genesis_block(self):
        bc = Blockchain()
        self.assertEqual(bc.chain[0].index, 0)
        self.assertEqual(bc.chain[0].previous_hash, "0")

    def test_add_transaction(self):
        bc = Blockchain()
        bc.add_transaction("A", "B", 10)
        self.assertEqual(len(bc.pending_transactions), 1)

    def test_chain_integrity(self):
        bc = Blockchain()
        bc.mine_pending_transactions("x")
        self.assertTrue(bc.is_chain_valid())
        # 篡改数据并再次检查
        bc.chain[1].transactions[0]['amount'] = 9999
        self.assertFalse(bc.is_chain_valid())

if __name__ == "__main__":
    unittest.main()

FAQ:快速扫清你的疑问

Q1. 只依赖 PoW 会不会太耗电?

公平地说,PoW 耗能确实是瓶颈。但在教学和小规模私有链场景下,几百万次哈希运算并不夸张;后续可用 PoS、DPoS 或 Raft 改良。

Q2. “挖矿奖励”数字从何而来?

奖励数量、出块时间、难度值均由社区治理规则决定。你可以在 mine_pending_transactions 中随意调整,早日体验量化宽松或供应紧缩。

Q3. 交易没有数字签名怎么办?

当前代码是“明文广播”示例。正式环境需引入 ECDSA non-repudiation:发送者用私钥签名交易,接收者用公钥验证交易真伪。Python 推荐库 ecdsa

Q4. 如何把链持久化到磁盘?

每次出块后将 my_chain.chain 序列化为 JSON,追加到 blockchain.json;启动时自动加载回内存。别忘了校验最后一个区块哈希。

Q5. 如何让多台节点达成共识?

第一步为节点暴露 HTTP API(Flask/FastAPI),广播交易和新区块;第二步实现最长链规则或 PBFT 投票。👉 这里有一份完整节点通信实战指南,帮你跳过 90 % 蹩脚手写!

进阶:把链升级为「小联盟链」

  1. 引入多重签名钱包:支持企业级审批。
  2. 使用 Merkle Tree:加速 SPV 轻节点同步。
  3. 内嵌智能合约:用 Python AST 解释器或 PyTeal 连接 Algorand。
  4. 部署到生产:Docker 打包,K8s 横向扩展,Prometheus 监控 CPU/内存。

总结:下一步怎么走?

恭喜你已拥有一条能跑、能动、能拒绝篡改的 最小可行性区块链 (MVP)。把它继续打包成 RESTful 接口,你就可以对接 Web3 前端、移动端钱包,或充当供应链溯源系统的 去中心化账本 后端。

小技巧:把本教程放进自己的 GitHub 仓库,邀请同行提 PR,从中学习 Peer Review 流程。这不仅锻炼代码嗅觉,也为日后参与大型公链开发蓄力。

现在,你已站在区块链开发的起跑线上。动手去迭代、优化、再造——也许下一个 低成本碳中和方案 就从你的 Python 脚本开始!