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----------------------------------------