成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何用Python創(chuàng)建眼下火爆的區(qū)塊鏈?這篇干貨請(qǐng)收藏

開發(fā) 后端 區(qū)塊鏈
對(duì)數(shù)字貨幣的崛起感到新奇的我們,并且想知道其背后的技術(shù)——區(qū)塊鏈?zhǔn)窃鯓訉?shí)現(xiàn)的。作者認(rèn)為最快的學(xué)習(xí)區(qū)塊鏈的方式是自己創(chuàng)建一個(gè),本文就跟隨作者用Python來(lái)創(chuàng)建一個(gè)區(qū)塊鏈。在實(shí)踐中學(xué)習(xí),通過(guò)構(gòu)建一個(gè)區(qū)塊鏈可以加深對(duì)區(qū)塊鏈的理解。

[[222726]]

對(duì)數(shù)字貨幣的崛起感到新奇的我們,并且想知道其背后的技術(shù)——區(qū)塊鏈?zhǔn)窃鯓訉?shí)現(xiàn)的。作者認(rèn)為最快的學(xué)習(xí)區(qū)塊鏈的方式是自己創(chuàng)建一個(gè),本文就跟隨作者用Python來(lái)創(chuàng)建一個(gè)區(qū)塊鏈。在實(shí)踐中學(xué)習(xí),通過(guò)構(gòu)建一個(gè)區(qū)塊鏈可以加深對(duì)區(qū)塊鏈的理解。

準(zhǔn)備工作

本文要求讀者對(duì)Python有基本的理解,能讀寫基本的Python,并且需要對(duì)HTTP請(qǐng)求有基本的了解。

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

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

確保已經(jīng)安裝Python3.6+, pip , Flask, requests,安裝方法:

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

同時(shí)還需要一個(gè)HTTP客戶端,比如Postman,cURL或其它客戶端。參考

https://github.com/xilibi2003/blockchain

開始創(chuàng)建Blockchain

新建一個(gè)文件 blockchain.py,本文所有的代碼都寫在這一個(gè)文件中,可以隨時(shí)參考

https://github.com/xilibi2003/blockchain

Blockchain類

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

 

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

Blockchain類用來(lái)管理鏈條,它能存儲(chǔ)交易,加入新塊等,下面我們來(lái)進(jìn)一步完善這些方法。

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

每個(gè)區(qū)塊包含屬性:索引(index),Unix時(shí)間戳(timestamp),交易列表(transactions),工作量證明(稍后解釋)以及前一個(gè)區(qū)塊的Hash值。以下是一個(gè)區(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ū)塊鏈的概念就清楚了,每個(gè)新的區(qū)塊都包含上一個(gè)區(qū)塊的Hash,這是關(guān)鍵的一點(diǎn),它保障了區(qū)塊鏈不可變性。如果攻擊者破壞了前面的某個(gè)區(qū)塊,那么后面所有區(qū)塊的Hash都會(huì)變得不正確。不理解的話,慢慢消化。

加入交易

接下來(lái)我們需要添加一個(gè)交易,來(lái)完善下new_transaction方法:

 

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

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

創(chuàng)建新塊

當(dāng)Blockchain實(shí)例化后,我們需要構(gòu)造一個(gè)創(chuàng)世塊(沒(méi)有前區(qū)塊的第一個(gè)區(qū)塊),并且給它加上一個(gè)工作量證明。每個(gè)區(qū)塊都需要經(jīng)過(guò)工作量證明,俗稱挖礦,稍后會(huì)繼續(xù)講解。為了構(gòu)造創(chuàng)世塊,我們還需要完善new_block(), new_transaction() 和hash() 方法:

 

  1. import hashlib  
  2. import json  
  3. from time import time  
  4.  
  5. class Blockchain(object):  
  6.    def __init__(self):  
  7.        self.current_transactions = []  
  8.        self.chain = []  
  9.  
  10.        # Create the genesis block  
  11.        self.new_block(previous_hash=1, proof=100)  
  12.  
  13.    def new_block(self, proof, previous_hash=None):  
  14.        "" 
  15.        生成新塊  
  16.        :param proof: <int> The proof given by the Proof of Work algorithm  
  17.        :param previous_hash: (Optional) <str> Hash of previous Block  
  18.        :return: <dict> New Block  
  19.        "" 
  20.        block = {  
  21.            'index': len(self.chain) + 1,  
  22.            'timestamp'time(),  
  23.            'transactions': self.current_transactions,  
  24.            'proof': proof,  
  25.            'previous_hash': previous_hash or self.hash(self.chain[-1]),  
  26.        }  
  27.  
  28.        # Reset the current list of transactions  
  29.        self.current_transactions = []  
  30.  
  31.        self.chain.append(block)  
  32.        return block  
  33.  
  34.    def new_transaction(self, sender, recipient, amount):  
  35.        "" 
  36.        生成新交易信息,信息將加入到下一個(gè)待挖的區(qū)塊中  
  37.        :param sender: <str> Address of the Sender  
  38.        :param recipient: <str> Address of the Recipient  
  39.        :param amount: <int> Amount  
  40.        :return: <int> The index of the Block that will hold this transaction  
  41.        "" 
  42.        self.current_transactions.append({  
  43.            'sender': sender,  
  44.            'recipient': recipient,  
  45.            'amount': amount,  
  46.        })  
  47.  
  48.        return self.last_block['index'] + 1   
  49.    @property  
  50.    def last_block(self):  
  51.        return self.chain[-1]  
  52.  
  53.    @staticmethod  
  54.    def hash(block): 
  55.        "" 
  56.        生成塊的 SHA-256 hash值  
  57.        :param block: <dict> Block  
  58.        :return: <str>  
  59.        "" 
  60.  
  61.        # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes  
  62.        block_string = json.dumps(block, sort_keys=True).encode()  
  63.        return hashlib.sha256(block_string).hexdigest() 

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

理解工作量證明

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

為了方便理解,舉個(gè)例子:假設(shè)一個(gè)整數(shù) x 乘以另一個(gè)整數(shù) y 的積的 Hash 值必須以 0 結(jié)尾,即hash(x * y) = ac23dc…0,設(shè)變量 x = 5,求 y 的值?用Python實(shí)現(xiàn)如下:

 

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

結(jié)果是y=21. 因?yàn)椋?/p>

 

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

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

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

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

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

 

  1. import hashlib  
  2. import json  
  3. from time import time  
  4. from uuid import uuid4  
  5.  
  6. class Blockchain(object):  
  7.    ...         
  8.  
  9.    def proof_of_work(self, last_proof):  
  10.        "" 
  11.        簡(jiǎn)單的工作量證明:  
  12.         - 查找一個(gè) p' 使得 hash(pp') 以4個(gè)0開頭  
  13.         - p 是上一個(gè)塊的證明,  p' 是當(dāng)前的證明  
  14.        :param last_proof: <int 
  15.        :return: <int 
  16.        "" 
  17.  
  18.        proof = 0  
  19.        while self.valid_proof(last_proof, proof) is False 
  20.            proof += 1   
  21.        return proof  
  22.  
  23.    @staticmethod  
  24.    def valid_proof(last_proof, proof):  
  25.        "" 
  26.        驗(yàn)證證明: 是否hash(last_proof, proof)以4個(gè)0開頭?  
  27.        :param last_proof: <int> Previous Proof  
  28.        :param proof: <intCurrent Proof  
  29.        :return: <bool> True if correct, False if not 
  30.        ""  
  31.  
  32.        guess = f'{last_proof}{proof}'.encode()  
  33.        guess_hash = hashlib.sha256(guess).hexdigest()  
  34.        return guess_hash[:4] == "0000" 

衡量算法復(fù)雜度的辦法是修改零開頭的個(gè)數(shù)。使用4個(gè)來(lái)用于演示,你會(huì)發(fā)現(xiàn)多一個(gè)零都會(huì)大大增加計(jì)算出結(jié)果所需的時(shí)間。現(xiàn)在Blockchain類基本已經(jīng)完成了,接下來(lái)使用HTTP requests來(lái)進(jìn)行交互。

Blockchain作為API接口

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

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

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

創(chuàng)建節(jié)點(diǎn)

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

 

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

簡(jiǎn)單的說(shuō)明一下以上代碼:

第15行: 創(chuàng)建一個(gè)節(jié)點(diǎn).

第18行: 為節(jié)點(diǎn)創(chuàng)建一個(gè)隨機(jī)的名字.

第21行: 實(shí)例Blockchain類.

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

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

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

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

發(fā)送交易

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

 

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

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

 

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

 

挖礦

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

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

 

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

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

運(yùn)行區(qū)塊鏈

你可以使用cURL 或Postman 去和API進(jìn)行交互,啟動(dòng)server:

 

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

讓我們通過(guò)請(qǐng)求 http://localhost:5000/mine 來(lái)進(jìn)行挖礦

 

通過(guò)post請(qǐng)求,添加一個(gè)新交易

 

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

 

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

在挖了兩次礦之后,就有3個(gè)塊了,通過(guò)請(qǐng)求 http://localhost:5000/chain 可以得到所有的塊信息。

 

  1.  
  2.  "chain": [  
  3.    {  
  4.      "index": 1,  
  5.      "previous_hash": 1,  
  6.      "proof": 100,  
  7.      "timestamp": 1506280650.770839,  
  8.      "transactions": []  
  9.    },  
  10.    {  
  11.      "index": 2,  
  12.      "previous_hash""c099bc...bfb7" 
  13.      "proof": 35293,  
  14.      "timestamp": 1506280664.717925,  
  15.      "transactions": [  
  16.        {  
  17.          "amount": 1,  
  18.          "recipient""8bbcb347e0634905b0cac7955bae152b" 
  19.          "sender""0"  
  20.        }  
  21.      ]  
  22.    },  
  23.    {  
  24.      "index": 3,  
  25.      "previous_hash""eff91a...10f2" 
  26.      "proof": 35089,  
  27.      "timestamp": 1506280666.1086972,  
  28.      "transactions": [  
  29.        {  
  30.          "amount": 1,  
  31.          "recipient""8bbcb347e0634905b0cac7955bae152b" 
  32.          "sender""0"  
  33.        }  
  34.      ]  
  35.    }  
  36.  ],  
  37.  "length": 3  

一致性(共識(shí))

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

注冊(cè)節(jié)點(diǎn)

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

  • /nodes/register 接收URL形式的新節(jié)點(diǎn)列表
  • /nodes/resolve 執(zhí)行一致性算法,解決任何沖突,確保節(jié)點(diǎn)擁有正確的鏈

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

 

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

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

實(shí)現(xiàn)共識(shí)算法

前面提到,沖突是指不同的節(jié)點(diǎn)擁有不同的鏈,為了解決這個(gè)問(wèn)題,規(guī)定最長(zhǎng)的、有效的鏈才是最終的鏈,換句話說(shuō),網(wǎng)絡(luò)中有效最長(zhǎng)鏈才是實(shí)際的鏈。我們使用一下的算法,來(lái)達(dá)到網(wǎng)絡(luò)中的共識(shí)。

 

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

第一個(gè)方法 valid_chain() 用來(lái)檢查是否是有效鏈,遍歷每個(gè)塊驗(yàn)證hash和proof;第二個(gè)方法 resolve_conflicts() 用來(lái)解決沖突,遍歷所有的鄰居節(jié)點(diǎn),并用上一個(gè)方法檢查鏈的有效性,如果發(fā)現(xiàn)有效更長(zhǎng)鏈,就替換掉自己的鏈。

讓我們添加兩個(gè)路由,一個(gè)用來(lái)注冊(cè)節(jié)點(diǎn),一個(gè)用來(lái)解決沖突。

 

  1. @app.route('/nodes/register', methods=['POST'])  
  2. def register_nodes():  
  3.    values = request.get_json()  
  4.  
  5.    nodes = values.get('nodes' 
  6.    if nodes is None:  
  7.        return "Error: Please supply a valid list of nodes", 400  
  8.  
  9.    for node in nodes:  
  10.        blockchain.register_node(node)  
  11.  
  12.    response = {  
  13.        'message''New nodes have been added' 
  14.        'total_nodes': list(blockchain.nodes),  
  15.    }  
  16.    return jsonify(response), 201  
  17.  
  18. @app.route('/nodes/resolve', methods=['GET'])  
  19. def consensus():  
  20.    replaced = blockchain.resolve_conflicts()  
  21.  
  22.    if replaced:  
  23.        response = {  
  24.            'message''Our chain was replaced' 
  25.            'new_chain': blockchain.chain  
  26.        }  
  27.    else 
  28.        response = {  
  29.            'message''Our chain is authoritative' 
  30.            'chain': blockchain.chain  
  31.        }    
  32.    return jsonify(response), 200 

你可以在不同的機(jī)器運(yùn)行節(jié)點(diǎn),或在一臺(tái)機(jī)機(jī)開啟不同的網(wǎng)絡(luò)端口來(lái)模擬多節(jié)點(diǎn)的網(wǎng)絡(luò),這里在同一臺(tái)機(jī)器開啟不同的端口演示,在不同的終端運(yùn)行一下命令,就啟動(dòng)了兩個(gè)節(jié)點(diǎn):http://localhost:5000 和 http://localhost:5001

 

  1. pipenv run python blockchain.py  
  2. pipenv run python blockchain.py -p 5001 

然后在節(jié)點(diǎn)2上挖兩個(gè)塊,確保是更長(zhǎng)的鏈,然后在節(jié)點(diǎn)1上訪問(wèn)接口/nodes/resolve ,這時(shí)節(jié)點(diǎn)1的鏈會(huì)通過(guò)共識(shí)算法被節(jié)點(diǎn)2的鏈取代。

 

好啦,你可以邀請(qǐng)朋友們一起來(lái)測(cè)試你的區(qū)塊鏈! 

責(zé)任編輯:龐桂玉 來(lái)源: 機(jī)器學(xué)習(xí)算法與Python學(xué)習(xí)
相關(guān)推薦

2021-09-29 16:53:53

區(qū)塊鏈數(shù)據(jù)技術(shù)

2017-08-03 13:36:22

2018-04-13 16:24:59

區(qū)塊鏈數(shù)據(jù)庫(kù)去中心化

2023-02-10 16:21:27

2022-05-30 15:27:48

數(shù)字資產(chǎn)NFT區(qū)塊鏈

2018-08-31 20:32:56

區(qū)塊鏈政府區(qū)塊鏈技術(shù)

2020-12-17 08:00:00

區(qū)塊鏈數(shù)據(jù)以太坊

2018-03-27 07:27:27

2021-09-23 22:40:10

區(qū)塊鏈比特幣技術(shù)

2022-05-23 10:00:15

醫(yī)療保健區(qū)塊鏈

2018-03-12 15:21:20

2019-02-12 21:15:00

2022-06-16 11:24:53

軟件安全區(qū)塊鏈去中心化

2018-03-27 09:52:30

區(qū)塊鏈數(shù)字貨幣比特幣

2021-04-08 18:39:57

JavaScriptExpress區(qū)塊鏈

2018-02-24 14:59:39

區(qū)塊鏈公共區(qū)塊鏈私有區(qū)塊鏈

2022-08-12 15:06:13

區(qū)塊鏈環(huán)境比特幣

2018-06-29 10:34:40

區(qū)塊鏈數(shù)字貨幣比特幣

2019-12-30 18:00:29

區(qū)塊鏈數(shù)字經(jīng)濟(jì)

2019-09-08 15:00:47

區(qū)塊鏈連鎖超市食品跟蹤
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲最大的黄色网址 | 一区亚洲 | 久久成人一区 | 91精品国产91久久久久久 | 亚洲精品一区二区三区在线 | 欧美一二三四成人免费视频 | 成人性视频免费网站 | 国产激情在线 | 久久国产视频一区 | 91看片在线 | 成人在线视频一区 | 亚洲欧美日韩成人在线 | 日本精品视频 | 成人精品一区二区三区 | 少妇精品亚洲一区二区成人 | 欧美日韩国产在线 | 色综网 | 久久综合一区 | 国产精品完整版 | 免费在线观看黄视频 | 国产精品久久久久9999鸭 | 日韩成人免费 | 中文字幕 在线观看 | 免费观看av网站 | 成人在线精品视频 | 高清亚洲 | 久久国品片 | 成人欧美一区二区三区在线播放 | 亚洲精品一区二区三区 | 91性高湖久久久久久久久_久久99 | 欧美性生活免费 | 国产一区二区免费电影 | 欧美freesex黑人又粗又大 | 久久网一区二区三区 | 免费中文字幕日韩欧美 | 亚洲一区二区久久 | av性色| 免费黄色a视频 | 青青久久久 | 亚洲成人第一页 | 国产精品乱码一区二区三区 |