运用datetime和hashlib模拟实现区块链
区块函数
包含区块高度标识:blockNo
交易数据:data
nonce值
preious_hash:上一个区块哈希
timestamp:当前时间
链函数
分别包括三个方法,添加块的方法、挖矿功能、以及打包交易
添加块的方法:
挖矿功能(采用的是工作量证明共识机制)
打包交易:模拟简单的打包交易的功能,哈希加密了最后的返回值
最后运行部分设置了20个区块上链
运行结果:
全部代码:
import datetimeimport hashlibimport randomclass Block:blockNo = 0data = Nonenext = Nonehash = Nonenonce = 0previous_hash = 0x0timestamp = datetime.datetime.now()def __init__(self, data):self.data = data# 添加哈希函数,计算区块的哈希值--将nonce、data、前一个 hash、timestamp和块号放入一个字符串并通过 SHA-256 函数运行def hash(self):h = hashlib.sha256()h.update(str(self.nonce).encode('utf-8') +str(self.data).encode('utf-8') +str(self.previous_hash).encode('utf-8') +str(self.timestamp).encode('utf-8') +str(self.blockNo).encode('utf-8'))return h.hexdigest()def __str__(self):return "Block Hash: " + str(self.hash()) + "\nBlockNo: " + str(self.blockNo) + "\nBlock Data: " + str(self.data) + "\nHashes: " + str(self.nonce) + "\n---------"# 区块链类class Blockchain:# 难度diff = 20# 最大随机数--设置为 2 的 32 次方,即 32 位数字中可以存储的最大数。随机数必须小于要接受的目标数maxNonce = 2 ** 32# 目标数--设置为 2 的 256 次方减去难度。在这种情况下,难度为 20target = 2 ** (256 - diff)# 区块链中的第一个块是创世块block = Block("Genesis")dummy = head = block# 添加块def add(self, block):# 前一个哈希设置为等于当前位于列表顶部的块block.previous_hash = self.block.hash()block.blockNo = self.block.blockNo + 1self.block.next = blockself.block = self.block.next# 添加了一个挖矿功能。我使用了工作量证明共识机制def mine(self, block):# 首先设置一些猜测准则(范围),从 0 到最大随机数for n in range(self.maxNonce):if int(block.hash(), 16) <= self.target:self.add(block)print(block)breakelse:block.nonce += 1# 打包交易def pack(self):data = ""transaction = {1: "A转账B 1bit \n",2: "A转账B 2bit \n",3: "A转账B 3bit \n",4: "A转账B 4bit \n",5: "A转账B 5bit \n",6: "A转账B 6bit \n",7: "A转账B 7bit \n",8: "A转账B 8bit \n",9: "A转账B 9bit \n",10: "A转账B 10bit \n",11: "A转账B 11bit \n",12: "A转账B 12bit \n",13: "A转账B 13bit \n",14: "A转账B 14bit \n",15: "A转账B 15bit \n",16: "A转账B 16bit \n",17: "A转账B 17bit \n",18: "A转账B 18bit \n",19: "A转账B 19bit \n",20: "A转账B 20bit \n",21: "A转账B 21bit \n",22: "A转账B 22bit \n",23: "A转账B 23bit \n",24: "A转账B 24bit \n",25: "A转账B 25bit \n",26: "A转账B 26bit \n",27: "A转账B 27bit \n",28: "A转账B 28bit \n",29: "A转账B 29bit \n",30: "A转账B 30bit \n",}for i in range(1, 6):index = random.randint(1, 30)data += transaction[index]hash_object = hashlib.sha256()hash_object.update(data.encode('utf-8'))hash_value = hash_object.hexdigest()return hash_valueif __name__ == '__main__':start = datetime.datetime.now()blockchain = Blockchain()num_of_blocks_to_add = 20# 它计算 num_of_blocks_to_add 个随机块for n in range(num_of_blocks_to_add):data = blockchain.pack()blockchain.mine(Block("Block " + str(n + 1) + data))while blockchain.head is not None:print(blockchain.head)blockchain.head = blockchain.head.nextend = datetime.datetime.now()print('Running time: %s Seconds' % (end - start))