python实现区块链

    技术2025-04-09  13

    区块结构:

    # 区块结构 class Block: ''' pre_hash:父区块哈希值 transaction:交易列表 timestamp:区块创建时间 hash:区块哈希值 nonce:随机值 ''' def __init__(self, transaction, pre_hash): # 将传入的父区块的哈希值和数据保存到类变量中 self.pre_hash = pre_hash self.transaction = transaction # 获取当前时间 self.timetamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.hash = None self.nonce = None # 计算区块的哈希值 message = hashlib.sha256() message.update(str(self.pre_hash).encode('utf-8')) message.update(str(self.transaction).encode('utf-8')) message.update(str(self.timetamp).encode('utf-8')) self.hash = message.hexdigest() def __repr__(self): return "区块内容:%s\n哈希值:%s" % (self.transaction, self.hash)

    区块链结构:

    # 区块链结构 class BlockChain: ''' blocks:包含的区块列表 ''' def __init__(self): self.blocks = [] # 添加区块 def addBlock(self, block): self.blocks.append(block)

    交易类:

    在实际的区块链中,数据不是简单的字符串,而是一个个交易记录, 包含交易的发送方、接收方、交易数量以及用来验证交易的发送方公钥和签名,所以定义一个包含这几个字段的交易类。

    class Transaction: # 初始化交易 def __init__(self, sender, recipient, amount): if isinstance(sender, bytes): sender = sender.decode('utf-8') self.sender = sender # 发送方 if isinstance(recipient, bytes): recipient = recipient.decode('utf-8') self.recipient = recipient # 接收方 self.amount = amount # 交易数量 # 验证交易可靠性,需要发送方的公钥和签名 def setSign(self, signature, pubkey): self.signature = signature # 发送方 self.pubkey = pubkey # 公钥 # 交易分为:挖矿所得、转账交易 # 挖矿所得无发送方,以此进行区分显示不同内容 def __repr__(self): if self.sender: s = "从%s转到%s %d 个加密货币" % (self.sender, self.recipient, self.amount) else: s = "%s挖矿获取 %d 个加密货币" % (self.recipient, self.amount) return s

    钱包:

    存放账户(一对唯一的公钥和私钥),即钱包的本质是生成和管理密钥对的工具。

    # 钱包 class Wallet: def __init__(self): # 基于椭圆曲线生成一个唯一的密钥对,代表区块链上一个唯一的账户 self.__private_key = SigningKey.generate(curve=SECP256k1) self.__public_key = self.__private_key.get_verifying_key() # 生成签名 # 通过公钥生成地址(公钥->hash->base64->地址) @property def address(self): h = hashlib.sha256(self.__public_key.to_pem()) return base64.b64encode(h.digest()) @property def pubkey(self): # 返回公钥字符串 return self.__public_key.to_pem() def sign(self, message): # 生成签名(是一串二进制字符串) h = hashlib.sha256(message.encode('utf8')) # 将二进制字符串转为ASCII进行输出 return binascii.hexlify(self.__private_key.sign(h.digest())) # 验证签名是否正确 def verifySign(self, pubkey, message, signature): verifier = VerifyingKey.from_pem(pubkey) h = hashlib.sha256(message.encode('utf8')) return verifier.verify(binascii.unhexlify(signature), h.digest())

    测试钱包的功能:

    # 测试钱包功能 wallet = Wallet() print(wallet.address) # 钱包地址 print(wallet.pubkey) # 钱包公钥 data = "交易数据" sg = wallet.sign(data) # 生成签名 print(sg) # 判断签名是否正确 print(wallet.verifySign(wallet.pubkey, data, sg))

    工作量证明:

    引入共识机制,选择最简单的PoW(工作量证明机制)。其原理是通过不断计算,找到一个随机数(nonce),使得生成的哈希值满足一定条件。

    # 工作量证明 class ProofOfWork: def __init__(self, block, miner, difficult=5): self.miner = miner self.block = block # 工作量难度,默认为5,表示有效的哈希值以5个0开头 self.difficult = difficult # 挖矿奖励,美完成一个区块可获得1个加密数字货币 self.reward = 1 # 挖矿函数:寻找nonce的值 def mine(self): i = 0 prefix = '0' * self.difficult while True: message = hashlib.sha256() message.update(str(self.block.pre_hash).encode('utf-8')) message.update(str(self.block.transaction).encode('utf-8')) message.update(str(self.block.timetamp).encode('utf-8')) message.update(str(i).encode('utf-8')) digest = message.hexdigest() if digest.startswith(prefix): self.block.nonce = i self.block.hash = digest return self.block i += 1 # 添加奖励 t = Transaction(sender="", recipient=self.miner.address, amount=self.reward) sig = self.miner.sign(json.dumps(t, cls=Transaction)) # sig = self.miner.sign(t) t.setSign(sig, self.miner.pubkey) self.block.transaction.append(t) # 验证区块有效性 def validate(self): message = hashlib.sha256() message.update(str(self.block.pre_hash).encode('utf-8')) message.update(str(self.block.transaction).encode('utf-8')) message.update(str(self.block.timetamp).encode('utf-8')) message.update(str(self.block.nonce).encode('utf-8')) digest = message.hexdigest() prefix = '0' * self.difficult return digest.startswith(prefix)

    getBalance()函数获取区块链中账户的加密数字货币信息

    # 获取区块链中加密数字货币情况 def getBalance(user): balance = 0 for block in bc.blocks: for t in block.transaction: if t.sender == user.address.decode(): # 如果用户是发送方 balance -= t.amount elif t.recipient == user.address.decode(): # 如果用户是接收方 balance += t.amount return balance

    测试整个区块链的交易情况:初始化一个区块链和3个钱包,查看钱包余额。

    # 创建一个区块链 bc = BlockChain() # 测试交易功能 a = Wallet() b = Wallet() c = Wallet() print("a:%d个加密货币" % (getBalance(a))) print("b:%d个加密货币" % (getBalance(b))) print("c:%d个加密货币" % (getBalance(c)))

    运行结果:余额均为 0

    a:0个加密货币 b:0个加密货币 c:0个加密货币

     

    Processed: 0.013, SQL: 9