引入共识机制(PoW)
import hashlibfrom datetime import datetimeclass Block:"""区块结构prev_hash:父区块哈希值data: 区块内容timestamp:区块创建时间hash: 区块哈希值Nonce:随机数"""def __init__(self, data, prev_hash):# 将传入的父哈希值和数据保存到类变量中self.prev_hash = prev_hashself.data = data# 获取当前时间self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")# 设置Nonce和哈希的初始值为Noneself.nonce = Noneself.hash = Nonedef __repr__(self):return "区块内容:%s\n哈希值: %s" % (self.data, self.hash)
class ProofOfWork:"""工作量证明"""def __init__(self, block, difficult=5):self.block = block# 定义工作量难度,默认为5,表示有效的哈希值以5个“0”开头self.difficulty = difficultdef mine(self):"""挖矿函数"""i = 0prefix = '0' * self.difficultywhile True:message = hashlib.sha256()message.update(str(self.block.prev_hash).encode('utf-8'))message.update(str(self.block.data).encode('utf-8'))message.update(str(self.block.timestamp).encode('utf-8'))message.update(str(i).encode("utf-8"))digest = message.hexdigest()if digest.startswith(prefix):self.block.nonce = iself.block.hash = digestreturn self.blocki += 1 //递加def validate(self):"""验证有效性"""message = hashlib.sha256()message.update(str(self.block.prev_hash).encode('utf-8'))message.update(str(self.block.data).encode('utf-8'))message.update(str(self.block.timestamp).encode('utf-8'))message.update(str(self.block.nonce).encode('utf-8'))digest = message.hexdigest()prefix = '0' * self.difficultyreturn digest.startswith(prefix)
`# 先定义一个区块
b = Block(data=“测试”, prev_hash=“”)
再定义一个工作量证明
w = ProofOfWork(b)`
# 进行挖矿,并统计函数执行时间#返回区块对象%timevalid_block= w.mine()
# 验证区块,并计算执行时间%timew.validate()#返回是否有效是否由5个0开头
class BlockChain:"""区块链结构体blocks:包含的区块列表"""def __init__(self):self.blocks = []def add_block(self, block):"""添加区块"""self.blocks.append(block)
blockchain = BlockChain()new_block1 = Block(data="创世区块", prev_hash="")w1 = ProofOfWork(new_block1)genesis_block = w1.mine()blockchain.add_block(genesis_block) #将生成的区块加入链nonce值是正确的new_block2 = Block(data="张三转给李四1个比特币", prev_hash=genesis_block.hash)w2 = ProofOfWork(new_block2)new_block = w2.mine()blockchain.add_block(new_block)new_block3 = Block(data="张三转给王五2个比特币", prev_hash=new_block.hash)w3 = ProofOfWork(new_block3)new_block = w3.mine()blockchain.add_block(new_block)
# 打印区块链print("区块链包含区块个数: %d\n" % len(blockchain.blocks))for block in blockchain.blocks:print("上一个区块哈希:%s" % block.prev_hash)print("区块内容:%s" % block.data)print("区块哈希:%s" % block.hash)print("\n")