使用python搭建简单的区块链,并实现数据上链
目录
一、引入库文件
引入所需的库文件,其中hashlib为核心文件。
import datetime
import hashlib
import time
二、编写消息类
通过编写消息类,将消息读入并进行哈希运算,与前面的消息进行连接等操作。
class Message:
def __init__(self, data):
self.hash = None
self.prev_hash = None
self.timestamp = time.time()
self.size = len(data.encode('utf-8'))
self.data = data
self.payload_hash = self._hash_payload()
def _hash_payload(self):
return hashlib.sha256(bytearray(str(self.timestamp) + str(self.data), "utf-8")).hexdigest()
def _hash_message(self):
return hashlib.sha256(bytearray(str(self.prev_hash) + self.payload_hash, "utf-8")).hexdigest()
def link(self, message):
""" 通过哈希将消息连接到上一条消息 """
self.prev_hash = message.hash
def seal(self):
""" 获取消息哈希 """
self.hash = self._hash_message()
三、编写区块类
通过编写区块类,使用前一区块的哈希值与时间戳等消息,将区块之间连接起来。
class Block:
def __init__(self, *args):
self.messages = []
self.timestamp = None
self.prev_hash = None
self.hash = None
if args:
for arg in args:
self.add_message(arg)
def _hash_block(self):
return hashlib.sha256(
bytearray(str(self.prev_hash) + str(self.timestamp) + self.messages[-1].hash, "utf-8")).hexdigest()
def add_message(self, message):
if len(self.messages) > 0:
message.link(self.messages[-1])
message.seal()
self.messages.append(message)
def link(self, block):
self.prev_hash = block.hash
def seal(self):
self.timestamp = time.time()
self.hash = self._hash_block()
def __repr__(self):
return '<hash: {}, prev_hash: {}, messages: {}, time: {}>'.format(
self.hash, self.prev_hash, len(self.messages), self.timestamp
)
四、编写区块链
编写区块链,完成区块上链的操作。
class SimpleChain:
def __init__(self):
self.chain = []
def add_block(self, block):
""" Add a block if valid."""
if len(self.chain) > 0:
block.prev_hash = self.chain[-1].hash
block.seal()
self.chain.append(block)
五、编写主函数
打印菜单,输入1,向当前块中添加消息内容。输入2,将当前块上链。输入3,查看区块链上的块。输入其他字符退出区块链并关闭程序。
def manager():
chain = SimpleChain()
block = Block()
msg = """
Action set:
- 向当前块中添加消息 (1)
- 将当前块添加到链 (2)
- 查看整条链上的块 (3)
- 终止程序并删除链 (0)
"""
print(msg)
while True:
print()
decide = input("Your action: ")
if decide == "1":
file = input("请输入文件名")
datafile = open(file, 'rb').read()
data = datafile.decode()
block.add_message(Message(data))
print("消息添加成功")
elif decide == "2":
if len(block.messages) > 0:
chain.add_block(block)
block = Block()
print("区块上链成功")
else:
print("当前块为空,无法上链。")
elif decide == "3":
n = 0
for b in chain.chain:
print("Block", n)
print(b)
print("--------------------------------------------------------------------------------------------")
n = n+1
else:
break
六、运行
if __name__ == "__main__":
manager()
运行程序,将要上链的内容放到py文件同级目录下,输入1,输入文件名向区块中添加消息,输入2将区块上链,输入3查看区块链上的内容,输入任意其他数字关闭程序并销毁链。