用python构建区块链(2)---工作量证明共识算法(proof of work)

mechanism.png

目录

用python构建区块链(1)---基本结构
用python构建区块链(2)---工作量证明共识算法(pow)

背景

  • 上一篇我们介绍了区块链的基本结构,今天我们在之前的基础上来简单实现一下工作量证明算法(proof of work),在介绍pow之前我们先思考一下为什么要工作量证明算法,或者再往前想一步为什么比特币如何解决信任的问题?
  • 比特币出现之前就有了拜占庭将军问题,主要思想是,如何在分布式系统环境里去相信其他人发给你的信息?下面是其描述:

一组拜占庭将军分别各率领一支军队共同围困一座城市。为了简化问题,将各支军队的行动策略限定为进攻或撤离两种。因为部分军队进攻部分军队撤离可能会造成灾难性后果,因此各位将军必须通过投票来达成一致策略,即所有军队一起进攻或所有军队一起撤离。因为各位将军分处城市不同方向,他们只能通过信使互相联系。在投票过程中每位将军都将自己投票给进攻还是撤退的信息通过信使分别通知其他所有将军,这样一来每位将军根据自己的投票和其他所有将军送来的信息就可以知道共同的投票结果而决定行动策略
系统的问题在于,将军中可能出现叛徒,他们不仅可能向较为糟糕的策略投票,还可能选择性地发送投票信息。假设有9位将军投票,其中1名叛徒。8名忠诚的将军中出现了4人投进攻,4人投撤离的情况。这时候叛徒可能故意给4名投进攻的将领送信表示投票进攻,而给4名投撤离的将领送信表示投撤离。这样一来在4名投进攻的将领看来,投票结果是5人投进攻,从而发起进攻;而在4名投撤离的将军看来则是5人投撤离。这样各支军队的一致协同就遭到了破坏。

拜占庭将军问题.png

比特币横空出世

  • 拜占庭将军问题主要问题是,中间人可以拦截消息,进行修改;上述的那些士兵可以理解成比特币中的一些节点,不是所有节点拿到消息后都是可以直接处理的,先去解决一个数学问题,就是工作量证明,只有拥有特定的计算能力解决了问题之后才能去修改或者校验(验证,打包,上链)。
工作量证明.png
  • 上图就是简单的工作量证明算法流程,一串数字后面有个x,x之前的数可以理解成交易数据,然后需要找到一个x,让整个数的hash值的开头有n个0,如果hash是很均匀的话,那么生成的hash值每一位为0或者1都是等可能的,所以前n个都为0的概率就是2的n次方/2的hash值位数,上图给出了如果hash值是5个bit的情况下的所有可能

渐入佳境

from hashlib import sha256
import time
class Block:
     
    def __init__(self,index,timestamp,data,previousHash=""):
        
        self.index = index
        self.timestamp = timestamp
        self.data = data
        self.previousHash = previousHash
        self.nonce = 0 //代表当前计算了多少次hash计算
        self.hash = self.calculateHash()
        
    
    def calculateHash(self):
        plainData = str(self.index)+str(self.timestamp)+str(self.data)+str(self.nonce)
        return sha256(plainData.encode('utf-8')).hexdigest()
    #挖矿 difficulty代表复杂度 表示前difficulty位都为0才算成功
    def minerBlock(self,difficulty):
        while(self.hash[0:difficulty]!=str(0).zfill(difficulty)):
            self.nonce+=1
            self.hash = self.calculateHash()
    
    def __str__(self):
        return str(self.__dict__)
    
    
class BlockChain:
    
    def __init__(self):
        self.chain = [self.createGenesisBlock()]
        self.difficulty = 5

    def createGenesisBlock(self):
        return Block(0,"01/01/2018","genesis block")
    
    def getLatestBlock(self):
        return self.chain[len(self.chain)-1]
    #添加区块前需要 做一道计算题😶,坐完后才能把区块加入到链上
    def addBlock(self,newBlock):
        newBlock.previousHash = self.getLatestBlock().hash
        newBlock.minerBlock(self.difficulty)
        self.chain.append(newBlock)
        
        
    
    def __str__(self):
        return str(self.__dict__)    
    
    def chainIsValid(self):
        for index in range(1,len(self.chain)):
            currentBlock = self.chain[index]
            previousBlock = self.chain[index-1]
            if (currentBlock.hash != currentBlock.calculateHash()):
                return False
            if previousBlock.hash != currentBlock.previousHash:
                return False
        return True
            
                  
myCoin = BlockChain()

# 下面打印了每个区块挖掘需要的时间 比特币通过一定的机制控制在10分钟出一个块 
# 其实就是根据当前网络算力 调整我们上面difficulty值的大小,如果你在
# 本地把上面代码difficulty的值调很大你可以看到很久都不会出计算结果
startMinerFirstBlockTime = time.time()
print("start to miner first block time :"+str(startMinerFirstBlockTime))

myCoin.addBlock(Block(1,"02/01/2018","{amount:4}"))

print("miner first block time completed" + ",used " +str(time.time()-startMinerFirstBlockTime) +"s")

startMinerSecondBlockTime = time.time()

print("start to miner first block time :"+str(startMinerSecondBlockTime))

myCoin.addBlock(Block(2,"03/01/2018","{amount:5}"))

print("miner second block time completed" + ",used " +str(time.time()-startMinerSecondBlockTime) +"s\n")

#print block info
print("print block info ####:\n")
for block in myCoin.chain:
    print("\n")
    print(block)
    
#check blockchain is valid
print("before tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())

#tamper the blockinfo
myCoin.chain[1].data = "{amount:1002}"
print("after tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())

习以为常

start to miner first block time :1524652057.52226
miner first block time completed,used 2.3928141593933105s
start to miner first block time :1524652059.915224
miner second block time completed,used 1.791139841079712s

print block info ####:

{'index': 0, 'timestamp': '01/01/2018', 'data': 'genesis block', 'previousHash': '', 'nonce': 0, 'hash': '1fb6344a6e5c8f0c7e03e1ded0e831a3d92c3741eb5f7153405b6107e3d8164b'}

{'index': 1, 'timestamp': '02/01/2018', 'data': '{amount:4}', 'previousHash': '1fb6344a6e5c8f0c7e03e1ded0e831a3d92c3741eb5f7153405b6107e3d8164b', 'nonce': 767597, 'hash': '000004c911b7d620a648fd8cec12d2d1cbe838c427f8cb2e12f00eaf64ffe1d3'}

{'index': 2, 'timestamp': '03/01/2018', 'data': '{amount:5}', 'previousHash': '000004c911b7d620a648fd8cec12d2d1cbe838c427f8cb2e12f00eaf64ffe1d3', 'nonce': 576083, 'hash': '00000b72782457590c470f83d574438b5bad3d8eb971e9f3e5d2a041107f8db3'}
before tamper block,blockchain is valid ###
True
after tamper block,blockchain is valid ###
False
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 拜占庭将军问题(Byzantine Generals Problem),是由莱斯利·兰波特在其同名论文中提出的分布...
    IT锟阅读 232评论 0 2
  • 又有段日子没更新了,为啥没更新? 有上分车队没?我玩诸葛亮贼6。战绩可查! 当然了,没更新,不是因为玩王者荣耀啦。...
    掌上ppt阅读 475评论 0 4
  • 这是谷雨第一次有别于传统手工艺的拍摄,而是选择了山歌这个题材;当然,严格来说仙居山歌也算传统手艺了,不过它的“艺”...
    谷雨CHN阅读 924评论 0 8
  • 【日更169】 又看了一部关于“安乐死”的纪录片《如何死亡:西蒙的抉择》,还是觉得这个话题非常具有现实意义。跟我上...
    唐斩2086阅读 242评论 0 0
  • “大圣,此去欲何?” “踏青天,碎凌霄。” “若一去不回...” "便一去不回!" 看完了悟空传,各有说辞。 早前...
    戚戚真小人wzj阅读 29,373评论 6 26