python实现简单的区块链
运用datetime和hashlib模拟实现区块链
区块函数
包含区块高度标识:blockNo
交易数据:data
nonce值
preious_hash:上一个区块哈希
timestamp:当前时间
链函数
分别包括三个方法,添加块的方法、挖矿功能、以及打包交易
添加块的方法:
挖矿功能(采用的是工作量证明共识机制)
打包交易:模拟简单的打包交易的功能,哈希加密了最后的返回值
最后运行部分设置了20个区块上链
运行结果:
全部代码:
import datetime
import hashlib
import random
class Block:
blockNo = 0
data = None
next = None
hash = None
nonce = 0
previous_hash = 0x0
timestamp = 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 次方减去难度。在这种情况下,难度为 20
target = 2 ** (256 - diff)
# 区块链中的第一个块是创世块
block = Block("Genesis")
dummy = head = block
# 添加块
def add(self, block):
# 前一个哈希设置为等于当前位于列表顶部的块
block.previous_hash = self.block.hash()
block.blockNo = self.block.blockNo + 1
self.block.next = block
self.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)
break
else:
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_value
if __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.next
end = datetime.datetime.now()
print('Running time: %s Seconds' % (end - start))