目录
一、引入库文件
二、编写消息类
三、编写区块类
四、编写区块链
五、编写主函数
六、运行
一、引入库文件
引入所需的库文件,其中hashlib为核心文件。
import datetimeimport hashlibimport time
二、编写消息类
通过编写消息类,将消息读入并进行哈希运算,与前面的消息进行连接等操作。
class Message:def __init__(self, data):self.hash = Noneself.prev_hash = Noneself.timestamp = time.time()self.size = len(data.encode('utf-8'))self.data = dataself.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.hashdef seal(self):""" 获取消息哈希 """self.hash = self._hash_message()
三、编写区块类
通过编写区块类,使用前一区块的哈希值与时间戳等消息,将区块之间连接起来。
class Block:def __init__(self, *args):self.messages = []self.timestamp = Noneself.prev_hash = Noneself.hash = Noneif 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.hashdef 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].hashblock.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 = 0for b in chain.chain:print("Block", n)print(b)print("--------------------------------------------------------------------------------------------")n = n+1else:break
六、运行
if __name__ == "__main__":manager()
运行程序,将要上链的内容放到py文件同级目录下,输入1,输入文件名向区块中添加消息,输入2将区块上链,输入3查看区块链上的内容,输入任意其他数字关闭程序并销毁链。