python系列:一个简易的区块链的实现tinyblockchains

浏览了一些区块链的基本资料,心血来潮,然后写了个tinyblockchains。于是乎,总结一下吧。关于自己对区块的一些认识。

区块链? 比特币 ? 傻傻分不清楚?

区块链(blockchains)是什么?通俗的解释就是一个分布式数据库。将区块高度、时间戳、存储数据、前一块区块哈希值用加密方法进行加密,(以sha256为例)通过哈希值建立链式连接。如果存储数据是记账数据,它便是一个分布式账本。

比特币(bitcoin)是一种加密虚拟货币,采取哈希加密、工作量证明机制(pow)是第一个采用了区块链技术的落地应用。根据全网算力,动态调节爆矿难度,通常出块时间是10分钟。


区块的基本结构是有区块高度、时间戳、存储数据、前一块区块哈希值、当前区块哈希值组成。

class Block(object):
    index = None 
    previous_hash = None
    timestamp = None
    data = None 
    hash = None

新的区块产生:

class Block(object):
    ...

    def create_start_block(self,index=0,previous_hash="",data="the block for gods"):        
        self.index = index
        self.previous_hash = previous_hash
        self.timestamp = date.datetime.now()
        self.data = data
        self.hash = Encrypt.hash_encrypt((str(self.index)+str(self.previous_hash)+str(self.timestamp)+str(self.data)).encode("utf-8"))
        pass

    def create_new_block(self,previous_block,data):
        self.index = previous_block.index + 1
        self.previous_hash = previous_block.hash
        self.timestamp = date.datetime.now()
        self.data = data
        self.hash = Encrypt.hash_encrypt((str(self.index)+str(self.previous_hash)+str(self.timestamp)+str(self.data)).encode("utf-8"))
        pass

注意:创世块即第一块区块是没有前一块的哈希值,为空。

加密数据生成(加密数据出来的哈希值有着生成慢,回验快的特性):

import hashlib

class Encrypt(object):
    @staticmethod
    def hash_encrypt(data_str):
         sha = hashlib.sha256()
         sha.update(data_str)
         return sha.hexdigest()

封装一层,建立区块创建者,方便上层调用。

class BlockCreater(object):
    @staticmethod
    def create_start_block(cls): 
        block = Block() 
        block.create_start_block()
        return block

    @staticmethod
    def create_new_block(cls,previous_block,data="new trade data"):
        block = Block()
        block.create_new_block(previous_block,data)
        return block

区块链上一个区块接着一个区块

class BlockChain(object):
    block_chains=[]

    def create_blockchain(self):
        self.block_chains.append(BlockCreater.create_start_block(BlockCreater))

    
    def add_new_block(self,data):
        while True:
            tblock = BlockCreater.create_new_block(BlockCreater,self.block_chains[-1],data)
            if Common_Recognise_POW.pow(tblock,self.block_chains[-1]):
                break
        print(Util.datetime2timestamp(tblock.timestamp) - Util.datetime2timestamp(self.block_chains[-1].timestamp))
        print("前导0个数:\n",Common_Recognise_POW.level)
        print("难度:\n",Common_Recognise_POW.difficulty)
        print("爆矿块:\n",tblock)
        self.block_chains.append(tblock)
        return tblock
        

然后新生成的区块,想要加入链,是有条件、有门槛的。以btc为例,它采取工作量证明,算出满足条件的区块的哈希值,全网在竞争计算这个特定值,哪个节点先算出这个值,就拥有将新区块写入链的权限了。(所以说,要写入链式有成本的,pow假设花费大量本)根据出块间隔时间,动态调整,哈希值难度,控制出块速度。

class Common_Recognise(object):
        pass
    
class Common_Recognise_POW(Common_Recognise):
    level = 0
    difficulty = ""
    generate_time = 10
    @staticmethod
    def pow(new_block,previous_block):
        flag = new_block.hash.startswith(Common_Recognise_POW.difficulty)
        if flag == True:
            Common_Recognise_POW.difficulty = ""
            for i in range(0,Common_Recognise_POW.level):
                Common_Recognise_POW.difficulty = Common_Recognise_POW.difficulty + "0"
            time_dis = (Util.datetime2timestamp(new_block.timestamp) - Util.datetime2timestamp(previous_block.timestamp))
                
            if time_dis  < Common_Recognise_POW.generate_time:
                Common_Recognise_POW.level = Common_Recognise_POW.level + 1
                pass
            elif time_dis  > Common_Recognise_POW.generate_time:
                Common_Recognise_POW.level = Common_Recognise_POW.level - 1        
                pass
        return flag
        pass

然后我们可以愉快运行下我们写的小型区块链

    
if __name__ == '__main__':
    demo = BlockChain()
    demo.create_blockchain()
    for i in range(1,20):
        demo.add_new_block("第"+str(i)+"笔交易")
    print(demo)
    pass

我们就可以看到:


0.0
前导0个数:
 1
难度:
 
爆矿块:
 index:1
previous_hash:a2404fb43bd66b34d223623ffcefc329f39e09796d18fcf933d08fccc1fb6def
timestamp:2018-03-18 11:03:45.632401
data:第1笔交易
hash:e947a936b39719c6851ac6f49bfb9c9a0f188f677c2f6477d4ab44f2b8cd04eb


0.0
前导0个数:
 2
难度:
 0
爆矿块:
 index:2
previous_hash:e947a936b39719c6851ac6f49bfb9c9a0f188f677c2f6477d4ab44f2b8cd04eb
timestamp:2018-03-18 11:03:45.683404
data:第2笔交易
hash:8e8669f23d52d52c707b9665265c05454404f202dcd5a0e02faff42a2f146c65

是不是一颗赛艇。。。<-.<-

源代码(源代码下载,点击打开链接)

# -*- coding: utf-8 -*-
# @Date    : 3:00 2018/3/18
# @Author  : kucece
# @github  : https://github.com/kucece
import hashlib
import datetime as date
import time

class Util(object):
    @staticmethod
    def datetime2timestamp(date_time):
        return time.mktime(date_time.timetuple())
    pass

class Encrypt(object):
    @staticmethod
    def hash_encrypt(data_str):
         sha = hashlib.sha256()
         sha.update(data_str)
         return sha.hexdigest()

class Block(object):
    index = None 
    previous_hash = None
    timestamp = None
    data = None 
    hash = None

    def create_start_block(self,index=0,previous_hash="",data="the block for gods"):        
        self.index = index
        self.previous_hash = previous_hash
        self.timestamp = date.datetime.now()
        self.data = data
        self.hash = Encrypt.hash_encrypt((str(self.index)+str(self.previous_hash)+str(self.timestamp)+str(self.data)).encode("utf-8"))
        pass

    def create_new_block(self,previous_block,data):
        self.index = previous_block.index + 1
        self.previous_hash = previous_block.hash
        self.timestamp = date.datetime.now()
        self.data = data
        self.hash = Encrypt.hash_encrypt((str(self.index)+str(self.previous_hash)+str(self.timestamp)+str(self.data)).encode("utf-8"))
        pass
    
    def __str__(self):
        return "index:"+str(self.index)+"\nprevious_hash:"+self.previous_hash+"\ntimestamp:"+str(self.timestamp)+"\ndata:"+self.data+"\nhash:"+self.hash+"\n\n"
        pass

class BlockCreater(object):
    @staticmethod
    def create_start_block(cls): 
        block = Block() 
        block.create_start_block()
        return block

    @staticmethod
    def create_new_block(cls,previous_block,data="new trade data"):
        block = Block()
        block.create_new_block(previous_block,data)
        return block
        


class BlockChain(object):
    block_chains=[]

    def create_blockchain(self):
        self.block_chains.append(BlockCreater.create_start_block(BlockCreater))

    
    def add_new_block(self,data):
        while True:
            tblock = BlockCreater.create_new_block(BlockCreater,self.block_chains[-1],data)
            if Common_Recognise_POW.pow(tblock,self.block_chains[-1]):
                break
        print(Util.datetime2timestamp(tblock.timestamp) - Util.datetime2timestamp(self.block_chains[-1].timestamp))
        print("前导0个数:\n",Common_Recognise_POW.level)
        print("难度:\n",Common_Recognise_POW.difficulty)
        print("爆矿块:\n",tblock)
        self.block_chains.append(tblock)
        return tblock
        

    def get_full_block_chains(self):
        return self.block_chains
    
    def __str__(self):
        content = ""
        for item in self.block_chains:
            content = content + str(item) + "\n"
        return content



class Common_Recognise(object):
        pass
    
class Common_Recognise_POW(Common_Recognise):
    level = 0
    difficulty = ""
    generate_time = 10
    @staticmethod
    def pow(new_block,previous_block):
        flag = new_block.hash.startswith(Common_Recognise_POW.difficulty)
        if flag == True:
            Common_Recognise_POW.difficulty = ""
            for i in range(0,Common_Recognise_POW.level):
                Common_Recognise_POW.difficulty = Common_Recognise_POW.difficulty + "0"
            time_dis = (Util.datetime2timestamp(new_block.timestamp) - Util.datetime2timestamp(previous_block.timestamp))
                
            if time_dis  < Common_Recognise_POW.generate_time:
                Common_Recognise_POW.level = Common_Recognise_POW.level + 1
                pass
            elif time_dis  > Common_Recognise_POW.generate_time:
                Common_Recognise_POW.level = Common_Recognise_POW.level - 1        
                pass
        return flag
        pass

    
if __name__ == '__main__':
    demo = BlockChain()
    demo.create_blockchain()
    for i in range(1,20):
        demo.add_new_block("第"+str(i)+"笔交易")
    print(demo)
    pass

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值