使用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查看区块链上的内容,输入任意其他数字关闭程序并销毁链。