zoukankan      html  css  js  c++  java
  • POW 工作量证明底层算法实现

    POW 算法说明

    比特币区块链通过竞争记账方式解决去中心化的账本一致性问题。竞争记账是过程,而不证明竞争结果。采用工作量证明(Proof of Work,PoW)的机制来实现竞争结果判定。

    哈希结果要满足前n位均为0要求,需要多次进行哈希值的计算。一般来说,n值越大,需要完成的哈希计算量也越大。要寻找4个前导0的哈希值,预期大概要进行2^16尝试。

    工作量证明的优缺点

    优点:完全去中心化,节点自由进出;

    缺点:目前已经吸引全球大部分的算力,其它再用Pow共识机制的区块链应用很难获得相同的算力来保障自身的安全;挖矿造成大量的资源浪费;tps较小,不能满足大量交易的需求。

    算法实现(Python)

      1 #!/usr/bin/env python3
      2 # -*- coding: utf-8 -*-
      3 """
      4  @desc:
      5  @author: xsmile
      6  @software: PyCharm  on 2020/6/14
      7 """
      8 import hashlib
      9 import time
     10 
     11 blocks = []
     12 
     13 
     14 class Block:
     15     """
     16     区块类
     17     """
     18     index = 0  # 全局记录区块总数
     19     Difficulty = 1
     20 
     21     def __init__(self, data, pre_hash, nonce):
     22         """
     23         初始化区块信息
     24         :param data: 区块携带数据
     25         :param pre_hash: 前一区块 hash 值
     26         :param nonce: 随机数
     27         :param difficulty: 挖矿难度
     28         """
     29         self.index = Block.index
     30         self.time_stamp = time.time()
     31         self.data = data
     32         self.pre_hash = pre_hash
     33         self.nonce = nonce
     34         self.hash_value = ''
     35         self.difficulty = Block.Difficulty
     36         Block.index += 1
     37 
     38 
     39 def block_hash(block):
     40     """
     41     生成区块成功验证后 hash 值
     42     :return: 区块 hash 值
     43     """
     44     block_info = str(block.index) + str(block.time_stamp) + str(block.data) + 
     45                  str(block.pre_hash) + str(block.nonce) + str(block.difficulty)
     46     block_hash = hashlib.sha3_256(block_info.encode('utf-8')).hexdigest()
     47 
     48     return block_hash
     49 
     50 
     51 def verify_hash(block):
     52     """
     53     验证区块 hash 是否符合难度要求
     54     :param block: 要被验证的区块
     55     :return: bool
     56     """
     57     pre_hash_difficult = '0' * block.difficulty
     58 
     59     return block.hash_value.startswith(pre_hash_difficult)
     60 
     61 
     62 def verify_block(new_block, last_block):
     63     verify_result = False
     64     if (new_block.index is last_block.index + 1) and (new_block.pre_hash is last_block.hash_value):
     65         verify_result = True
     66 
     67     return verify_result
     68 
     69 
     70 def create_block(last_block, data):
     71     """
     72     创建新区块
     73     :param last_block: 当前区块链上最后一个区块
     74     :param data: 区块数据
     75     :return: 挖矿成功的区块
     76     """
     77     new_block = Block(data=data, pre_hash=last_block.hash_value, nonce=0)
     78     while True:
     79         current_hash = block_hash(new_block)
     80         print('挖矿中.......当前 hash:', current_hash)
     81         new_block.hash_value = current_hash
     82         if verify_hash(new_block):
     83             if verify_block(new_block=new_block, last_block=last_block):
     84                 print('挖矿成功')
     85                 break
     86         new_block.nonce += 1
     87 
     88     return new_block
     89 
     90 
     91 def create_genesis_block():
     92     """
     93     创建创世区块
     94     :return: 返回创世区块
     95     """
     96     block = Block(data='', pre_hash='', nonce=0)
     97     block.hash_value = block_hash(block)
     98     return block
     99 
    100 
    101 def run():
    102     """
    103     代码执行
    104     :return: None
    105     """
    106     genesis_block = create_genesis_block()
    107     blocks.append(genesis_block)
    108     new_block = create_block(last_block=blocks[-1], data='俊伟君')
    109     blocks.append(new_block)
    110     print('end')
    111 
    112 
    113     pass
    114 
    115 
    116 if __name__ == "__main__":
    117     run()
    118     pass

    代码说明

    主要用到 hashlib 库对区块进行 hash 运算得到 64 位 hash 值以及 time 库产生时间戳。

    运用 Python 中的列表存储区块(建议实现链表方式)

    代码运行结果

    Connected to pydev debugger (build 192.5728.105)
    挖矿中.......当前 hash: 41f48e701967a748eee9fdb48d09c7db4758df1890f9d6983b7fdda44fec9825
    挖矿中.......当前 hash: 62b7dff450e1b028d875c94459194701df16cdde690ef2ebee740ae7012112a3
    挖矿中.......当前 hash: 7dbb0e167cc36b40e81a0ea4ead2434ccca606f34b574f63343e578aa702e3bf
    挖矿中.......当前 hash: b27693b2e92a6c7595175a3ebdfa04a5185c3d5fa5059d8e76c34c60ba7e50ec
    挖矿中.......当前 hash: 339159298fc8956454cd0f57fa1410149acac3c68dd21319b10fd6824fa9331e
    挖矿中.......当前 hash: cba34c177d3371f6f4eaee68ea1f145ee9b143f0b6006ed5f6ba2d5c2022b694
    挖矿中.......当前 hash: f05ec6d5d5a59697b3dce25defd706fc9f4c72d31e33cf0f30803ef6b68f4a2d
    挖矿中.......当前 hash: 9ca3acbca0cf80c664ee131fa4bdba41c5c649cffb8a14bafd488e85a469ed96
    挖矿中.......当前 hash: cfb9cfa6365a7d8815b019008f477a288e006f1646a6eaf9db7f4751c10a9383
    挖矿中.......当前 hash: 4aab3ab7959646d5068db581460a7bc92a8fddf4290e731c7857a78ffe446428
    挖矿中.......当前 hash: 05a309e03f5c22b3f30b08d29c1ab4462e237e3ce27bdbc9b2efaf0a56402c03
    挖矿成功

    在挖矿难度设置为 1 的时候,运行多次的结果中得出,基本会在大概第7次 nounce 时得到结果。

    产生的区块结构如下:

    ----------------------------------------声明----------------------------------------

    参考内容:https://www.jianshu.com/p/6f9efb979a13

    仅自己学习过程技术总结,如有哪里有误的地方,欢迎指正。

    原创不易,如需转载,请注明出处及地址 https://www.cnblogs.com/xsmile/

    ----------------------------------------end----------------------------------------

  • 相关阅读:
    SpringCloud教程五:Zuul(路由+过滤)
    ubuntu18.0.4 不能下载 libgd2-dev
    ubuntu18.04下安装中文输入法
    Ubuntu下tomcat启动报错:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
    Java面试题汇总(一)
    Redis常见面试题
    Docker是什么
    Django实现自动发布(1数据模型)
    数据随机分配的思考
    单链表反转
  • 原文地址:https://www.cnblogs.com/xsmile/p/13125380.html
Copyright © 2011-2022 走看看