为了账号安全,请及时绑定邮箱和手机立即绑定

区块链、区块、交易简单实现

标签:
区块链

简单的区块链、区块、交易逻辑结构与代码实现。

1.区块链逻辑结构

https://img1.sycdn.imooc.com//5d311c830001906b07420504.jpg

区块链的逻辑结构

block_chain是一个区块链,block是一个区块,message是消息,transcation是交易。
一个区块链是多个区块的连接;一个区块包含多个消息;一个消息有一个交易。

2.区块链类图

https://img1.sycdn.imooc.com//5d311c8700017b3e07180385.jpg

区块链类图

3.代码

以下四个类可直接执行看效果,感受区块链、区块、消息、交易的数据结构。

Transcation.py

import datetimeclass Transcation:
    def __init__(self,payer,recer,money):        self.payer = payer        self.recer = recer        self.money = money        self.timestamp = datetime.datetime.now()    def __repr__(self):        return str(self.payer) + " pay " + str(self.recer) + " " + str(self.money) + " " + str(self.timestamp)if __name__ == "__main__":
    t1 = Transcation("I","him",10)
    print(t1)

NiuMessage.py

import hashlib
import datetime
from Transcation import Transcationclass NiuMessage:

    def __init__(self,transcation):        self.transcation = transcation        self.hash = None        self.pre_hash = None        self.timestamp = datetime.datetime.now()        self.payload_hash = self._hash_payload() #交易后的hash

    def _hash_payload(self): #对交易时间与数据进行hash
        return hashlib.sha256( (str(self.timestamp) + str(self.transcation)).encode("utf-8") ).hexdigest()    def _hash_message(self): #将前一个hash与交易后的hash,再hash
        return hashlib.sha256( (str(self.pre_hash) + str(self._hash_payload())).encode("utf-8") ).hexdigest()    def seal(self): #就是将交易hash,设置为现在的hash,这里为什么不能赋值在构造器,因为构造器不能调用两个函数
        self.hash = self._hash_message()    def __repr__(self):
        mystr = "hash:{} , pre_hash:{} , data:{}".format(self.hash,self.pre_hash,self.transcation)        return mystr    def validate(self,Message): #上个交易的hash与数据要能对上
        if (Message.hash != self.pre_hash):
            raise InvalidateMessage("交易hash被篡改 ," + str(self))        if(Message.hash != Message._hash_message()):
            raise InvalidateMessage("交易数据被篡改 ,"+str(self))    def link(self,Message):        self.pre_hash = Message.hashclass InvalidateMessage(Exception):
    def __init__(self,*args,**kwargs):
        Exception.__init__(self,*args,**kwargs)if __name__ == "__main__":
    t1 = Transcation("I", "him", 10)
    t2 = Transcation("him", "it", 10)
    t3 = Transcation("it", "her", 10)

    m1 = NiuMessage(t1)
    m1.seal()

    m2 = NiuMessage(t2)
    m2.link(m1)
    m2.seal()
    m2.validate(m1)

    m3 = NiuMessage(t3)
    m3.link(m2)
    m3.seal()
    m3.validate(m2)

    print(m1)
    print(m2)
    print(m3)    #m2.hash="33"  '3448aa15999c2f73e61e5bfc4a72286823a6b52d23bf571d9fcbb7ba631bed97'
    #m2.transcation = "fda"
    #m3.validate(m2)

NiuBlock.py

import hashlib
import datetime
from NiuMessage import NiuMessage
from Transcation import Transcation
from NiuMessage import InvalidateMessageclass NiuBlock:
    def __init__(self,*args):        self.hash = None        self.pre_hash = None        self.timestamp = None        self.message_list = [] #存储多个交易记录
        if args:
            for arg in args:
                self.add_message(arg) #一次打包多个交易进区块

    def add_message(self,message): #将message放进区块的message列表中
        if(len(self.message_list)>0):
            message.link(self.message_list[-1]) #message与上一个message相连
        message.seal() #这是message的seal,不是block的seal
        if (len(self.message_list) > 0):
            message.validate(self.message_list[-1]) #这是message的validate,不是block的
        self.message_list.append(message)    def link(self,block):        self.pre_hash = block.hash    def seal(self):        self.timestamp = datetime.datetime.now()        self.hash = self.hash_block()    def hash_block(self):        return hashlib.sha256( (str(self.pre_hash) + \
                                str(self.timestamp) + \
                                str(self.message_list[-1].hash)).encode("utf-8") ).hexdigest()    def validate(self,block):#验证block
        if (block.hash != self.pre_hash):
            raise InvalidBlockException("区块hash被篡改 ," + str(self))    def validate_message_list(self):#验证消息列表
        for i,message in enumerate(self.message_list):            if i>0 :
                message.validate(self.message_list[i-1])        return str(self) + " ,数据ok"

    def __repr__(self):        return "money block=hash:{},pre_hash:{},len:{},timestamp:{}".\
            format(self.hash,self.pre_hash,len(self.message_list),self.timestamp)class InvalidBlockException(Exception):
    def __init__(self,*args,**kwargs):
        Exception.__init__(self,*args,**kwargs)if __name__ == "__main__":    try:
        t1 = Transcation("I", "him", 10)
        t2 = Transcation("him", "it", 10)
        t3 = Transcation("it", "her", 10)

        m1 = NiuMessage(t1)
        m2 = NiuMessage(t2)
        m3 = NiuMessage(t3)

        niu = NiuBlock(m1,m2,m3)
        niu.seal()        #m2.hash = "hehe"

        #niu.message_list[1] = m3

        print(niu.validate_message_list()) #仅是校验message,还不是校验区块之间的连接
    except InvalidateMessage as e:
        print(e)
    except InvalidBlockException as e:
        print(e)

NiuBlockChain.py

from NiuMessage import NiuMessagefrom Transcation import Transcationfrom NiuMessage import InvalidateMessagefrom NiuBlock import InvalidBlockExceptionfrom NiuBlock import NiuBlockclass NiuBlockChain:
    def __init__(self):
        self.block_list = []    def __repr__(self):
        mystr = "block chain:\n"
        for i,block in enumerate(blockchain.block_list):
            mystr += "block {} , {}  \n".format(i,block)            for j,message in enumerate(block.message_list):
                mystr += "  message {}\n".format(message)        return mystr    def add_block(self,block):
        if(len(self.block_list) > 0):
            block.link(self.block_list[-1])
        block.seal()        if (len(self.block_list) > 0):
            block.validate(self.block_list[-1])
        self.block_list.append(block)    def validate_block_list(self):
        for i,block in enumerate(self.block_list):            if i>0 :                try:
                    block.validate(self.block_list[i-1])                except InvalidateBlockChainException as e:                    raise InvalidateBlockChainException("无效blockchain,区块被修改")        return str(self) + " ,数据ok"class InvalidateBlockChainException(Exception):
        def __init__(self, *args, **kwargs):
            Exception.__init__(self, *args, **kwargs)if __name__ == "__main__":    try:

        blockchain = NiuBlockChain()

        t1 = Transcation("I", "him", 10)
        t2 = Transcation("him", "it", 10)
        t3 = Transcation("it", "her", 10)
        t4 = Transcation("her", "mm", 10)
        t5 = Transcation("mm", "gg", 10)
        t6 = Transcation("gg", "pp", 10)

        m1 = NiuMessage(t1)
        m2 = NiuMessage(t2)
        m3 = NiuMessage(t3)
        m4 = NiuMessage(t4)
        m5 = NiuMessage(t5)
        m6 = NiuMessage(t6)

        b1 = NiuBlock(m1,m2)
        blockchain.add_block(b1)

        b2 = NiuBlock(m3)
        blockchain.add_block(b2)

        b3 = NiuBlock(m4,m5,m6)
        blockchain.add_block(b3)        #blockchain.add_block(b2) 测试区块被修改

        print(blockchain.validate_block_list())    except InvalidateMessage as e:
        print(e)    except InvalidBlockException as e:
        print(e)    except InvalidateBlockChainException as e:
        print(e)

https://img1.sycdn.imooc.com//5d311c8f0001dc4407280121.jpg

NiuBlockChain执行结果

可以看出区块链区块之间由hash连接,区块中交易的消息也是由hash连接,一旦任何数据被修改,hash之间就连接不上了。



作者:浮云发发
链接:https://www.jianshu.com/p/3b2826ea7746


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 1
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消