日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
用Python從零開始創(chuàng)建區(qū)塊鏈

作者認(rèn)為最快的學(xué)習(xí)區(qū)塊鏈的方式是自己創(chuàng)建一個,本文就跟隨作者用Python來創(chuàng)建一個區(qū)塊鏈。

創(chuàng)新互聯(lián)主要從事網(wǎng)站制作、成都網(wǎng)站設(shè)計、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)慶陽,十載網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575

對數(shù)字貨幣的崛起感到新奇的我們,并且想知道其背后的技術(shù)——區(qū)塊鏈?zhǔn)窃鯓訉崿F(xiàn)的。

但是完全搞懂區(qū)塊鏈并非易事,我喜歡在實踐中學(xué)習(xí),通過寫代碼來學(xué)習(xí)技術(shù)會掌握得更牢固。通過構(gòu)建一個區(qū)塊鏈可以加深對區(qū)塊鏈的理解。

準(zhǔn)備工作

本文要求讀者對Python有基本的理解,能讀寫基本的Python,并且需要對HTTP請求有基本的了解。

我們知道區(qū)塊鏈?zhǔn)怯蓞^(qū)塊的記錄構(gòu)成的不可變、有序的鏈結(jié)構(gòu),記錄可以是交易、文件或任何你想要的數(shù)據(jù),重要的是它們是通過哈希值(hashes)鏈接起來的。

如果你還不是很了解哈希,可以查看這篇文章

環(huán)境準(zhǔn)備

環(huán)境準(zhǔn)備,確保已經(jīng)安裝Python3.6+, pip , Flask, requests

安裝方法:

 
 
 
 
  1. pip install Flask==0.12.2 requests==2.18.4 

同時還需要一個HTTP客戶端,比如Postman,cURL或其它客戶端。

參考源代碼(原代碼在我翻譯的時候,無法運行,我fork了一份,修復(fù)了其中的錯誤,并添加了翻譯,感謝star)

開始創(chuàng)建Blockchain

新建一個文件 blockchain.py,本文所有的代碼都寫在這一個文件中,可以隨時參考源代碼

Blockchain類

首先創(chuàng)建一個Blockchain類,在構(gòu)造函數(shù)中創(chuàng)建了兩個列表,一個用于儲存區(qū)塊鏈,一個用于儲存交易。

以下是Blockchain類的框架:

 
 
 
 
  1. class Blockchain(object): 
  2.     def __init__(self): 
  3.         self.chain = [] 
  4.         self.current_transactions = [] 
  5.     def new_block(self): 
  6.         # Creates a new Block and adds it to the chain 
  7.         pass 
  8.     def new_transaction(self): 
  9.         # Adds a new transaction to the list of transactions 
  10.         pass 
  11.     @staticmethod 
  12.     def hash(block): 
  13.         # Hashes a Block 
  14.         pass 
  15.     @property 
  16.     def last_block(self): 
  17.         # Returns the last Block in the chain 
  18.         pass 

 

Blockchain類用來管理鏈條,它能存儲交易,加入新塊等,下面我們來進一步完善這些方法。

塊結(jié)構(gòu)

每個區(qū)塊包含屬性:索引(index),Unix時間戳(timestamp),交易列表(transactions),工作量證明(稍后解釋)以及前一個區(qū)塊的Hash值。

以下是一個區(qū)塊的結(jié)構(gòu):

 
 
 
 
  1. block = { 
  2.     'index': 1, 
  3.     'timestamp': 1506057125.900785, 
  4.     'transactions': [ 
  5.         { 
  6.             'sender': "8527147fe1f5426f9dd545de4b27ee00", 
  7.             'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f", 
  8.             'amount': 5, 
  9.         } 
  10.     ], 
  11.     'proof': 324984774000, 
  12.     'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" 

 

到這里,區(qū)塊鏈的概念就清楚了,每個新的區(qū)塊都包含上一個區(qū)塊的Hash,這是關(guān)鍵的一點,它保障了區(qū)塊鏈不可變性。如果攻擊者破壞了前面的某個區(qū)塊,那么后面所有區(qū)塊的Hash都會變得不正確。不理解的話,慢慢消化,可參考區(qū)塊鏈記賬原理

加入交易

接下來我們需要添加一個交易,來完善下new_transaction方法

 
 
 
 
  1. class Blockchain(object): 
  2.  
  3.     ... 
  4.  
  5.     def new_transaction(self, sender, recipient, amount): 
  6.  
  7.         """ 
  8.  
  9.         生成新交易信息,信息將加入到下一個待挖的區(qū)塊中 
  10.  
  11.         :param sender:  Address of the Sender 
  12.  
  13.         :param recipient:  Address of the Recipient 
  14.  
  15.         :param amount:  Amount 
  16.  
  17.         :return:  The index of the Block that will hold this transaction 
  18.  
  19.         """ 
  20.  
  21.         self.current_transactions.append({ 
  22.  
  23.             'sender': sender, 
  24.  
  25.             'recipient': recipient, 
  26.  
  27.             'amount': amount, 
  28.  
  29.         }) 
  30.  
  31.         return self.last_block['index'] + 1 

 

方法向列表中添加一個交易記錄,并返回該記錄將被添加到的區(qū)塊(下一個待挖掘的區(qū)塊)的索引,等下在用戶提交交易時會有用。

創(chuàng)建新塊

當(dāng)Blockchain實例化后,我們需要構(gòu)造一個創(chuàng)世塊(沒有前區(qū)塊的第一個區(qū)塊),并且給它加上一個工作量證明。

每個區(qū)塊都需要經(jīng)過工作量證明,俗稱挖礦,稍后會繼續(xù)講解。

為了構(gòu)造創(chuàng)世塊,我們還需要完善newblock(), newtransaction() 和hash() 方法:

 
 
 
 
  1. import hashlib 
  2.  
  3. import json 
  4.  
  5. from time import time 
  6.  
  7. class Blockchain(object): 
  8.  
  9.     def __init__(self): 
  10.  
  11.         self.current_transactions = [] 
  12.  
  13.         self.chain = [] 
  14.  
  15.         # Create the genesis block 
  16.  
  17.         self.new_block(previous_hash=1, proof=100) 
  18.  
  19.     def new_block(self, proof, previous_hash=None): 
  20.  
  21.         """ 
  22.  
  23.         生成新塊 
  24.  
  25.         :param proof:  The proof given by the Proof of Work algorithm 
  26.  
  27.         :param previous_hash: (Optional)  Hash of previous Block 
  28.  
  29.         :return:  New Block 
  30.  
  31.         """ 
  32.  
  33.         block = { 
  34.  
  35.             'index': len(self.chain) + 1, 
  36.  
  37.             'timestamp': time(), 
  38.  
  39.             'transactions': self.current_transactions, 
  40.  
  41.             'proof': proof, 
  42.  
  43.             'previous_hash': previous_hash or self.hash(self.chain[-1]), 
  44.  
  45.         } 
  46.  
  47.         # Reset the current list of transactions 
  48.  
  49.         self.current_transactions = [] 
  50.  
  51.         self.chain.append(block) 
  52.  
  53.         return block 
  54.  
  55.     def new_transaction(self, sender, recipient, amount): 
  56.  
  57.         """ 
  58.  
  59.         生成新交易信息,信息將加入到下一個待挖的區(qū)塊中 
  60.  
  61.         :param sender:  Address of the Sender 
  62.  
  63.         :param recipient:  Address of the Recipient 
  64.  
  65.         :param amount:  Amount 
  66.  
  67.         :return:  The index of the Block that will hold this transaction 
  68.  
  69.         """ 
  70.  
  71.         self.current_transactions.append({ 
  72.  
  73.             'sender': sender, 
  74.  
  75.             'recipient': recipient, 
  76.  
  77.             'amount': amount, 
  78.  
  79.         }) 
  80.  
  81.         return self.last_block['index'] + 1 
  82.  
  83.     @property 
  84.  
  85.     def last_block(self): 
  86.  
  87.         return self.chain[-1] 
  88.  
  89.     @staticmethod 
  90.  
  91.     def hash(block): 
  92.  
  93.         """ 
  94.  
  95.         生成塊的 SHA-256 hash值 
  96.  
  97.         :param block:  Block 
  98.  
  99.         :return:  
  100.  
  101.         """ 
  102.  
  103.         # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes 
  104.  
  105.         block_string = json.dumps(block, sort_keys=True).encode() 
  106.  
  107.         return hashlib.sha256(block_string).hexdigest() 

 

通過上面的代碼和注釋可以對區(qū)塊鏈有直觀的了解,接下來我們看看區(qū)塊是怎么挖出來的。

理解工作量證明

新的區(qū)塊依賴工作量證明算法(PoW)來構(gòu)造。PoW的目標(biāo)是找出一個符合特定條件的數(shù)字,這個數(shù)字很難計算出來,但容易驗證。這就是工作量證明的核心思想。

為了方便理解,舉個例子:

假設(shè)一個整數(shù) x 乘以另一個整數(shù) y 的積的 Hash 值必須以 0 結(jié)尾,即 hash(x * y) = ac23dc…0。設(shè)變量 x = 5,求 y 的值?

用Python實現(xiàn)如下:

 
 
 
 
  1. from hashlib import sha256 
  2.  
  3. x = 5 
  4.  
  5. y = 0  # y未知 
  6.  
  7. while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0": 
  8.  
  9.     y += 1 
  10.  
  11. print(f'The solution is y = {y}') 

 

結(jié)果是y=21. 因為:

 
 
 
 
  1. hash(5 * 21) = 1253e9373e...5e3600155e860 

在比特幣中,使用稱為Hashcash的工作量證明算法,它和上面的問題很類似。礦工們?yōu)榱藸帄Z創(chuàng)建區(qū)塊的權(quán)利而爭相計算結(jié)果。通常,計算難度與目標(biāo)字符串需要滿足的特定字符的數(shù)量成正比,礦工算出結(jié)果后,會獲得比特幣獎勵。

當(dāng)然,在網(wǎng)絡(luò)上非常容易驗證這個結(jié)果。

實現(xiàn)工作量證明

讓我們來實現(xiàn)一個相似PoW算法,規(guī)則是:尋找一個數(shù) p,使得它與前一個區(qū)塊的 proof 拼接成的字符串的 Hash 值以 4 個零開頭。

 
 
 
 
  1. import hashlib 
  2.  
  3. import json 
  4.  
  5. from time import time 
  6.  
  7. from uuid import uuid4 
  8.  
  9. class Blockchain(object): 
  10.  
  11.     ... 
  12.  
  13.     def proof_of_work(self, last_proof): 
  14.  
  15.         """ 
  16.  
  17.         簡單的工作量證明: 
  18.  
  19.          - 查找一個 p' 使得 hash(pp') 以4個0開頭 
  20.  
  21.          - p 是上一個塊的證明,  p' 是當(dāng)前的證明 
  22.  
  23.         :param last_proof:  
  24.  
  25.         :return:  
  26.  
  27.         """ 
  28.  
  29.         proof = 0 
  30.  
  31.         while self.valid_proof(last_proof, proof) is False: 
  32.  
  33.             proof += 1 
  34.  
  35.         return proof 
  36.  
  37.     @staticmethod 
  38.  
  39.     def valid_proof(last_proof, proof): 
  40.  
  41.         """ 
  42.  
  43.         驗證證明: 是否hash(last_proof, proof)以4個0開頭? 
  44.  
  45.         :param last_proof:  Previous Proof 
  46.  
  47.         :param proof:  Current Proof 
  48.  
  49.         :return:  True if correct, False if not. 
  50.  
  51.         """ 
  52.  
  53.         guess = f'{last_proof}{proof}'.encode() 
  54.  
  55.         guess_hash = hashlib.sha256(guess).hexdigest() 
  56.  
  57.         return guess_hash[:4] == "0000" 

 

衡量算法復(fù)雜度的辦法是修改零開頭的個數(shù)。使用4個來用于演示,你會發(fā)現(xiàn)多一個零都會大大增加計算出結(jié)果所需的時間。

現(xiàn)在Blockchain類基本已經(jīng)完成了,接下來使用HTTP requests來進行交互。

Blockchain作為API接口

我們將使用Python Flask框架,這是一個輕量Web應(yīng)用框架,它方便將網(wǎng)絡(luò)請求映射到 Python函數(shù),現(xiàn)在我們來讓Blockchain運行在基于Flask web上。

我們將創(chuàng)建三個接口:

  • /transactions/new 創(chuàng)建一個交易并添加到區(qū)塊
  • /mine 告訴服務(wù)器去挖掘新的區(qū)塊
  • /chain 返回整個區(qū)塊鏈

創(chuàng)建節(jié)點

我們的“Flask服務(wù)器”將扮演區(qū)塊鏈網(wǎng)絡(luò)中的一個節(jié)點。我們先添加一些框架代碼:

 
 
 
 
  1. import hashlib 
  2.  
  3. import json 
  4.  
  5. from textwrap import dedent 
  6.  
  7. from time import time 
  8.  
  9. from uuid import uuid4 
  10.  
  11. from flask import Flask 
  12.  
  13. class Blockchain(object): 
  14.  
  15.     ... 
  16.  
  17. # Instantiate our Node 
  18.  
  19. app = Flask(__name__) 
  20.  
  21. # Generate a globally unique address for this node 
  22.  
  23. node_identifier = str(uuid4()).replace('-', '') 
  24.  
  25. # Instantiate the Blockchain 
  26.  
  27. blockchain = Blockchain() 
  28.  
  29. @app.route('/mine', methods=['GET']) 
  30.  
  31. def mine(): 
  32.  
  33.     return "We'll mine a new Block" 
  34.  
  35. @app.route('/transactions/new', methods=['POST']) 
  36.  
  37. def new_transaction(): 
  38.  
  39.     return "We'll add a new transaction" 
  40.  
  41. @app.route('/chain', methods=['GET']) 
  42.  
  43. def full_chain(): 
  44.  
  45.     response = { 
  46.  
  47.         'chain': blockchain.chain, 
  48.  
  49.         'length': len(blockchain.chain), 
  50.  
  51.     } 
  52.  
  53.     return jsonify(response), 200 
  54.  
  55. if __name__ == '__main__': 
  56.  
  57.     app.run(host='0.0.0.0', port=5000) 

 

簡單的說明一下以上代碼:

第15行: 創(chuàng)建一個節(jié)點.

第18行: 為節(jié)點創(chuàng)建一個隨機的名字.

第21行: 實例Blockchain類.

第24–26行: 創(chuàng)建/mine GET接口。

第28–30行: 創(chuàng)建/transactions/new POST接口,可以給接口發(fā)送交易數(shù)據(jù).

第32–38行: 創(chuàng)建 /chain 接口, 返回整個區(qū)塊鏈。

第40–41行: 服務(wù)運行在端口5000上.

發(fā)送交易

發(fā)送到節(jié)點的交易數(shù)據(jù)結(jié)構(gòu)如下:

 
 
 
 
  1.  
  2.  "sender": "my address", 
  3.  
  4.  "recipient": "someone else's address", 
  5.  
  6.  "amount": 5 
  7.  

 

之前已經(jīng)有添加交易的方法,基于接口來添加交易就很簡單了

 
 
 
 
  1. import hashlib 
  2.  
  3. import json 
  4.  
  5. from textwrap import dedent 
  6.  
  7. from time import time 
  8.  
  9. from uuid import uuid4 
  10.  
  11. from flask import Flask, jsonify, request 
  12.  
  13. ... 
  14.  
  15. @app.route('/transactions/new', methods=['POST']) 
  16.  
  17. def new_transaction(): 
  18.  
  19.     values = request.get_json() 
  20.  
  21.     # Check that the required fields are in the POST'ed data 
  22.  
  23.     required = ['sender', 'recipient', 'amount'] 
  24.  
  25.     if not all(k in values for k in required): 
  26.  
  27.         return 'Missing values', 400 
  28.  
  29.     # Create a new Transaction 
  30.  
  31.     index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount']) 
  32.  
  33.     response = {'message': f'Transaction will be added to Block {index}'} 
  34.  
  35.     return jsonify(response), 201 

 

挖礦

挖礦正是神奇所在,它很簡單,做了一下三件事:

  • 計算工作量證明PoW
  • 通過新增一個交易授予礦工(自己)一個幣
  • 構(gòu)造新區(qū)塊并將其添加到鏈中

 

 
 
 
 
  1. import hashlib 
  2.  
  3. import json 
  4.  
  5. from time import time 
  6.  
  7. from uuid import uuid4 
  8.  
  9. from flask import Flask, jsonify, request 
  10.  
  11. ... 
  12.  
  13. @app.route('/mine', methods=['GET']) 
  14.  
  15. def mine(): 
  16.  
  17.     # We run the proof of work algorithm to get the next proof... 
  18.  
  19.     last_block = blockchain.last_block 
  20.  
  21.     last_proof = last_block['proof'] 
  22.  
  23.     proof = blockchain.proof_of_work(last_proof) 
  24.  
  25.     # 給工作量證明的節(jié)點提供獎勵. 
  26.  
  27.     # 發(fā)送者為 "0" 表明是新挖出的幣 
  28.  
  29.     blockchain.new_transaction( 
  30.  
  31.         sender="0", 
  32.  
  33.         recipient=node_identifier, 
  34.  
  35.         amount=1, 
  36.  
  37.     ) 
  38.  
  39.     # Forge the new Block by adding it to the chain 
  40.  
  41.     block = blockchain.new_block(proof) 
  42.  
  43.     response = { 
  44.  
  45.         'message': "New Block Forged", 
  46.  
  47.         'index': block['index'], 
  48.  
  49.         'transactions': block['transactions'], 
  50.  
  51.         'proof': block['proof'], 
  52.  
  53.         'previous_hash': block['previous_hash'], 
  54.  
  55.     } 
  56.  
  57.     return jsonify(response), 200 

 

注意交易的接收者是我們自己的服務(wù)器節(jié)點,我們做的大部分工作都只是圍繞Blockchain類方法進行交互。到此,我們的區(qū)塊鏈就算完成了,我們來實際運行下

運行區(qū)塊鏈

你可以使用cURL 或Postman 去和API進行交互

啟動server:

 
 
 
 
  1. $ python blockchain.py 
  2.  
  3. * Runing on http://127.0.0.1:5000/ (Press CTRL+C to quit) 

 

讓我們通過請求 http://localhost:5000/mine 來進行挖礦

用Postman請求挖礦

通過post請求,添加一個新交易

用Postman請求挖礦

如果不是使用Postman,則用一下的cURL語句也是一樣的:

 
 
 
 
  1. $ curl -X POST -H "Content-Type: application/json" -d '{ 
  2.  
  3.  "sender": "d4ee26eee15148ee92c6cd394edd974e", 
  4.  
  5.  "recipient": "someone-other-address", 
  6.  
  7.  "amount": 5 
  8.  
  9. }' "http://localhost:5000/transactions/new" 

 

在挖了兩次礦之后,就有3個塊了,通過請求 http://localhost:5000/chain 可以得到所有的塊信息。

 
 
 
 
  1.  
  2.   "chain": [ 
  3.  
  4.     { 
  5.  
  6.       "index": 1, 
  7.  
  8.       "previous_hash": 1, 
  9.  
  10.       "proof": 100, 
  11.  
  12.       "timestamp": 1506280650.770839, 
  13.  
  14.       "transactions": [] 
  15.  
  16.     }, 
  17.  
  18.     { 
  19.  
  20.       "index": 2, 
  21.  
  22.       "previous_hash": "c099bc...bfb7", 
  23.  
  24.       "proof": 35293, 
  25.  
  26.       "timestamp": 1506280664.717925, 
  27.  
  28.       "transactions": [ 
  29.  
  30.         { 
  31.  
  32.           "amount": 1, 
  33.  
  34.           "recipient": "8bbcb347e0634905b0cac7955bae152b", 
  35.  
  36.           "sender": "0" 
  37.  
  38.         } 
  39.  
  40.       ] 
  41.  
  42.     }, 
  43.  
  44.     { 
  45.  
  46.       "index": 3, 
  47.  
  48.       "previous_hash": "eff91a...10f2", 
  49.  
  50.       "proof": 35089, 
  51.  
  52.       "timestamp": 1506280666.1086972, 
  53.  
  54.       "transactions": [ 
  55.  
  56.         { 
  57.  
  58.           "amount": 1, 
  59.  
  60.           "recipient": "8bbcb347e0634905b0cac7955bae152b", 
  61.  
  62.           "sender": "0" 
  63.  
  64.         } 
  65.  
  66.       ] 
  67.  
  68.     } 
  69.  
  70.   ], 
  71.  
  72.   "length": 3 
  73.  

 

一致性(共識)

我們已經(jīng)有了一個基本的區(qū)塊鏈可以接受交易和挖礦。但是區(qū)塊鏈系統(tǒng)應(yīng)該是分布式的。既然是分布式的,那么我們究竟拿什么保證所有節(jié)點有同樣的鏈呢?這就是一致性問題,我們要想在網(wǎng)絡(luò)上有多個節(jié)點,就必須實現(xiàn)一個一致性的算法。

注冊節(jié)點

在實現(xiàn)一致性算法之前,我們需要找到一種方式讓一個節(jié)點知道它相鄰的節(jié)點。每個節(jié)點都需要保存一份包含網(wǎng)絡(luò)中其它節(jié)點的記錄。因此讓我們新增幾個接口:

/nodes/register 接收URL形式的新節(jié)點列表

/nodes/resolve執(zhí)行一致性算法,解決任何沖突,確保節(jié)點擁有正確的鏈

我們修改下Blockchain的init函數(shù)并提供一個注冊節(jié)點方法:

 
 
 
 
  1. ... 
  2.  
  3. from urllib.parse import urlparse 
  4.  
  5. ... 
  6.  
  7. class Blockchain(object): 
  8.  
  9.     def __init__(self): 
  10.  
  11.         ... 
  12.  
  13.         self.nodes = set() 
  14.  
  15.         ... 
  16.  
  17.     def register_node(self, address): 
  18.  
  19.         """ 
  20.  
  21.         Add a new node to the list of nodes 
  22.  
  23.         :param address:  Address of node. Eg. 'http://192.168.0.5:5000' 
  24.  
  25.         :return: None 
  26.  
  27.         """ 
  28.  
  29.         parsed_url = urlparse(address) 
  30.  
  31.         self.nodes.add(parsed_url.netloc) 

 

我們用 set 來儲存節(jié)點,這是一種避免重復(fù)添加節(jié)點的簡單方法。

實現(xiàn)共識算法

前面提到,沖突是指不同的節(jié)點擁有不同的鏈,為了解決這個問題,規(guī)定最長的、有效的鏈才是最終的鏈,換句話說,網(wǎng)絡(luò)中有效最長鏈才是實際的鏈。

我們使用一下的算法,來達到網(wǎng)絡(luò)中的共識

 
 
 
 
  1. ... 
  2.  
  3. import requests 
  4.  
  5. class Blockchain(object) 
  6.  
  7.     ... 
  8.  
  9.     def valid_chain(self, chain): 
  10.  
  11.         """ 
  12.  
  13.         Determine if a given blockchain is valid 
  14.  
  15.         :param chain:  A blockchain 
  16.  
  17.         :return:  True if valid, False if not 
  18.  
  19.         """ 
  20.  
  21.         last_block = chain[0] 
  22.  
  23.         current_index = 1 
  24.  
  25.         while current_index < len(chain): 
  26.  
  27.             block = chain[current_index] 
  28.  
  29.             print(f'{last_block}') 
  30.  
  31.             print(f'{block}') 
  32.  
  33.             print("\n-----------\n") 
  34.  
  35.             # Check that the hash of the block is correct 
  36.  
  37.             if block['previous_hash'] != self.hash(last_block): 
  38.  
  39.                 return False 
  40.  
  41.             # Check that the Proof of Work is correct 
  42.  
  43.             if not self.valid_proof(last_block['proof'], block['proof']): 
  44.  
  45.                 return False 
  46.  
  47.             last_block = block 
  48.  
  49.             current_index += 1 
  50.  
  51.         return True 
  52.  
  53.     def resolve_conflicts(self): 
  54.  
  55.         """ 
  56.  
  57.         共識算法解決沖突 
  58.  
  59.         使用網(wǎng)絡(luò)中最長的鏈. 
  60.  
  61.         :return:  True 如果鏈被取代, 否則為False 
  62.  
  63.         """ 
  64.  
  65.         neighbours = self.nodes 
  66.  
  67.         new_chain = None 
  68.  
  69.         # We're only looking for chains longer than ours 
  70.  
  71.         max_length = len(self.chain) 
  72.  
  73.         # Grab and verify the chains from all the nodes in our network 
  74.  
  75.         for node in neighbours: 
  76.  
  77.             response = requests.get(f'http://{node}/chain') 
  78.  
  79.             if response.status_code == 200: 
  80.  
  81.                 length = response.json()['length'] 
  82.  
  83.                 chain = response.json()['chain'] 
  84.  
  85.                 # Check if the length is longer and the chain is valid 
  86.  
  87.                 if length > max_length and self.valid_chain(chain): 
  88.  
  89.                     max_length = length 
  90.  
  91.                     new_chain = chain 
  92.  
  93.         # Replace our chain if we discovered a new, valid chain longer than ours 
  94.  
  95.         if new_chain: 
  96.  
  97.             self.chain = new_chain 
  98.  
  99.             return True 
  100.  
  101.         return False 

 

第一個方法 valid_chain() 用來檢查是否是有效鏈,遍歷每個塊驗證hash和proof.

第2個方法 resolve_conflicts() 用來解決沖
網(wǎng)站名稱:用Python從零開始創(chuàng)建區(qū)塊鏈
網(wǎng)站地址:http://www.dlmjj.cn/article/djedipd.html