从 0 开始,用 Python 写区块链:如何实现一个简单的区块链?
现在放在 github 上面,目前写到第 4 课了,每一课单独一个文件夹。
目前实现了简单的区块链,准备每天更新一课。
从 0 开始,用 Python 写区块链:如何实现一个简单的区块链?
放[]里就是区块链了吗,真搞笑
我来给你一个从零开始的Python区块链实现。这个例子会包含区块结构、链式连接和工作量证明。
import hashlib
import json
import time
from typing import List, Dict, Any
class Block:
def __init__(self, index: int, timestamp: float, transactions: List[Dict], previous_hash: str):
self.index = index
self.timestamp = timestamp
self.transactions = transactions
self.previous_hash = previous_hash
self.nonce = 0
self.hash = self.calculate_hash()
def calculate_hash(self) -> str:
block_string = json.dumps({
"index": self.index,
"timestamp": self.timestamp,
"transactions": self.transactions,
"previous_hash": self.previous_hash,
"nonce": self.nonce
}, sort_keys=True).encode()
return hashlib.sha256(block_string).hexdigest()
def mine_block(self, difficulty: int):
target = "0" * difficulty
while self.hash[:difficulty] != target:
self.nonce += 1
self.hash = self.calculate_hash()
print(f"区块 {self.index} 挖矿完成: {self.hash}")
class Blockchain:
def __init__(self):
self.chain: List[Block] = []
self.difficulty = 4
self.pending_transactions = []
self.create_genesis_block()
def create_genesis_block(self):
genesis_block = Block(0, time.time(), [], "0")
genesis_block.mine_block(self.difficulty)
self.chain.append(genesis_block)
def get_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):
block = Block(
len(self.chain),
time.time(),
self.pending_transactions,
self.get_latest_block().hash
)
block.mine_block(self.difficulty)
self.chain.append(block)
self.pending_transactions = []
# 给矿工奖励
self.add_transaction("系统", miner_address, 1.0)
def is_chain_valid(self) -> bool:
for i in range(1, len(self.chain)):
current_block = self.chain[i]
previous_block = self.chain[i-1]
# 检查当前区块哈希是否正确
if current_block.hash != current_block.calculate_hash():
return False
# 检查是否链接到前一个区块
if current_block.previous_hash != previous_block.hash:
return False
# 检查工作量证明
if current_block.hash[:self.difficulty] != "0" * self.difficulty:
return False
return True
def display_chain(self):
for block in self.chain:
print(f"\n区块 #{block.index}")
print(f"时间戳: {block.timestamp}")
print(f"交易数: {len(block.transactions)}")
print(f"前哈希: {block.previous_hash}")
print(f"当前哈希: {block.hash}")
print(f"Nonce: {block.nonce}")
# 使用示例
if __name__ == "__main__":
# 创建区块链
my_blockchain = Blockchain()
# 添加一些交易
my_blockchain.add_transaction("Alice", "Bob", 5.0)
my_blockchain.add_transaction("Bob", "Charlie", 3.0)
# 挖矿(矿工地址为"Miner1")
print("开始挖矿...")
my_blockchain.mine_pending_transactions("Miner1")
# 再添加一些交易并挖矿
my_blockchain.add_transaction("Charlie", "Alice", 2.0)
my_blockchain.mine_pending_transactions("Miner2")
# 显示区块链
print("\n=== 区块链信息 ===")
my_blockchain.display_chain()
# 验证区块链
print(f"\n区块链是否有效: {my_blockchain.is_chain_valid()}")
这个实现包含了区块链的核心概念:
- 区块结构:每个区块包含索引、时间戳、交易列表、前一个区块的哈希、随机数(nonce)和当前哈希
- 哈希计算:使用SHA-256算法确保数据完整性
- 工作量证明:通过挖矿过程(找到特定难度的哈希)来创建新区块
- 链式连接:每个区块都包含前一个区块的哈希,形成不可篡改的链
- 交易系统:简单的交易记录和矿工奖励机制
运行这个代码,你会看到区块链的创建过程、交易添加、挖矿操作以及最终的链结构展示。你可以调整难度值来改变挖矿的计算复杂度。
总结:从区块结构开始,逐步实现链式连接和工作量证明。
一个区块的哈希和前一个哈希能对上,就形成了区块链。
KV 数据库了解下
python 的轻量级 dbm 如何? 或者你建议用 redis ?
不错, 大力支持, 希望楼主能坚持下去!
最新更新:
区块链两个节点之间可以同步数据了。
但是,还没有完成数据验证。
下一节课,将要写完数据验证。
增加了节点同步的区块链
增加一个 list,保存节点。<br>nodes=[]<br>
为了方便同步数据,我们要增加一个接口,可以获知区块链高度。
http://localhost:8080/blocks/height
这样,即可得到区块链的高度。当目标节点的区块链高度大于本地区块链高度时,才去同步。
查看节点
http://localhost:8080/nodes
添加节点
http://localhost:8080/nodes/add/localhost/9000
得到:<br>[<br> {<br> "ip": "localhost",<br> "port": 9000<br> }<br>]<br>
在 8080 的节点中加入另一个节点 8081
http://localhost:8080/nodes/add/localhost/8081
查看 8080 节点
http://localhost:8080/nodes
在 8081 的区块链中加一条信息
http://localhost:8081/say/jerry2
在 8080 节点中同步
http://localhost:8080/blocks/sync
查看节点
如果没同步:<br>"no synced"<br>
如果同步了:<br>"synced"<br>
http://localhost:8080/blocks/all
详情,在 https://github.com/OpensourceBooks/blockchain/blob/master/5/readme.md

