日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
想學(xué)習(xí)區(qū)塊鏈?那就用Python構(gòu)建一個

了解區(qū)塊鏈?zhǔn)侨绾喂ぷ鞯淖羁斓姆椒ㄊ菢?gòu)建一個。

在承德等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站制作、網(wǎng)站設(shè)計、外貿(mào)網(wǎng)站建設(shè) 網(wǎng)站設(shè)計制作按需設(shè)計,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,成都全網(wǎng)營銷推廣,外貿(mào)營銷網(wǎng)站建設(shè),承德網(wǎng)站建設(shè)費用合理。

你看到這篇文章是因為和我一樣,對加密貨幣的大熱而感到興奮。并且想知道區(qū)塊鏈?zhǔn)侨绾喂ぷ鞯?—— 它們背后的技術(shù)基礎(chǔ)是什么。

但是理解區(qū)塊鏈并不容易 —— 至少對我來說是這樣。我徜徉在各種難懂的視頻中,并且因為示例太少而陷入深深的挫敗感中。

我喜歡在實踐中學(xué)習(xí)。這會使得我在代碼層面上處理主要問題,從而可以讓我堅持到底。如果你也是這么做的,在本指南結(jié)束的時候,你將擁有一個功能正常的區(qū)塊鏈,并且實實在在地理解了它的工作原理。

開始之前 …

記住,區(qū)塊鏈?zhǔn)且粋€ 不可更改的、有序的 記錄(被稱為區(qū)塊)的鏈。它們可以包括交易transaction、文件或者任何你希望的真實數(shù)據(jù)。最重要的是它們是通過使用哈希鏈接到一起的。

如果你不知道哈希是什么,這里有解釋。

本指南的目標(biāo)讀者是誰? 你應(yīng)該能輕松地讀、寫一些基本的 Python 代碼,并能夠理解 HTTP 請求是如何工作的,因為我們討論的區(qū)塊鏈將基于 HTTP。

我需要做什么? 確保安裝了 Python 3.6+(以及 pip),還需要去安裝 Flask 和非常好用的 Requests 庫:

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

當(dāng)然,你也需要一個 HTTP 客戶端,像 Postman 或者 cURL。哪個都行。

最終的代碼在哪里可以找到? 源代碼在 這里。 

第 1 步:構(gòu)建一個區(qū)塊鏈

打開你喜歡的文本編輯器或者 IDE,我個人喜歡 PyCharm。創(chuàng)建一個名為 blockchain.py 的新文件。我將僅使用一個文件,如果你看暈了,可以去參考 源代碼。 

描述一個區(qū)塊鏈

我們將創(chuàng)建一個 Blockchain 類,它的構(gòu)造函數(shù)將去初始化一個空列表(去存儲我們的區(qū)塊鏈),以及另一個列表去保存交易。下面是我們的類規(guī)劃:

 
 
 
 
  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 類的原型

我們的 Blockchain 類負(fù)責(zé)管理鏈。它將存儲交易并且有一些為鏈中增加新區(qū)塊的輔助性質(zhì)的方法?,F(xiàn)在我們開始去充實一些類的方法。

區(qū)塊是什么樣子的?

每個區(qū)塊有一個索引、一個時間戳(Unix 時間)、一個交易的列表、一個證明(后面會詳細(xì)解釋)、以及前一個區(qū)塊的哈希。

單個區(qū)塊的示例應(yīng)該是下面的樣子:

 
 
 
 
  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"
  13. }

我們的區(qū)塊鏈中的塊示例

此刻,鏈的概念應(yīng)該非常明顯 —— 每個新區(qū)塊包含它自身的信息和前一個區(qū)域的哈希。這一點非常重要,因為這就是區(qū)塊鏈不可更改的原因:如果攻擊者修改了一個早期的區(qū)塊,那么所有的后續(xù)區(qū)塊將包含錯誤的哈希。

這樣做有意義嗎?如果沒有,就讓時間來埋葬它吧 —— 這就是區(qū)塊鏈背后的核心思想。 

添加交易到一個區(qū)塊

我們將需要一種區(qū)塊中添加交易的方式。我們的 new_transaction() 就是做這個的,它非常簡單明了:

 
 
 
 
  1. class Blockchain(object):
  2. ... 
  3. def new_transaction(self, sender, recipient, amount):
  4. """
  5. Creates a new transaction to go into the next mined Block
  6. :param sender: Address of the Sender
  7. :param recipient: Address of the Recipient
  8. :param amount: Amount
  9. :return: The index of the Block that will hold this transaction
  10. """ 
  11. self.current_transactions.append({
  12. 'sender': sender,
  13. 'recipient': recipient,
  14. 'amount': amount,
  15. }) 
  16. return self.last_block['index'] + 1

new_transaction() 運行后將在列表中添加一個交易,它返回添加交易后的那個區(qū)塊的索引 —— 那個區(qū)塊接下來將被挖礦。提交交易的用戶后面會用到這些。 

創(chuàng)建新區(qū)塊

當(dāng)我們的 Blockchain 被實例化后,我們需要一個創(chuàng)世區(qū)塊(一個沒有祖先的區(qū)塊)來播種它。我們也需要去添加一些 “證明” 到創(chuàng)世區(qū)塊,它是挖礦(工作量證明 PoW)的成果。我們在后面將討論更多挖礦的內(nèi)容。

除了在我們的構(gòu)造函數(shù)中創(chuàng)建創(chuàng)世區(qū)塊之外,我們還需要寫一些方法,如 new_block()、new_transaction() 以及 hash()

 
 
 
 
  1. import hashlib
  2. import json
  3. from time import time  
  4. class Blockchain(object):
  5. def __init__(self):
  6. self.current_transactions = []
  7. self.chain = [] 
  8. # Create the genesis block
  9. self.new_block(previous_hash=1, proof=100) 
  10. def new_block(self, proof, previous_hash=None):
  11. """
  12. Create a new Block in the Blockchain
  13. :param proof: The proof given by the Proof of Work algorithm
  14. :param previous_hash: (Optional) Hash of previous Block
  15. :return: New Block
  16. """ 
  17. block = {
  18. 'index': len(self.chain) + 1,
  19. 'timestamp': time(),
  20. 'transactions': self.current_transactions,
  21. 'proof': proof,
  22. 'previous_hash': previous_hash or self.hash(self.chain[-1]),
  23. } 
  24. # Reset the current list of transactions
  25. self.current_transactions = [] 
  26. self.chain.append(block)
  27. return block 
  28. def new_transaction(self, sender, recipient, amount):
  29. """
  30. Creates a new transaction to go into the next mined Block
  31. :param sender: Address of the Sender
  32. :param recipient: Address of the Recipient
  33. :param amount: Amount
  34. :return: The index of the Block that will hold this transaction
  35. """
  36. self.current_transactions.append({
  37. 'sender': sender,
  38. 'recipient': recipient,
  39. 'amount': amount,
  40. }) 
  41. return self.last_block['index'] + 1 
  42. @property
  43. def last_block(self):
  44. return self.chain[-1] 
  45. @staticmethod
  46. def hash(block):
  47. """
  48. Creates a SHA-256 hash of a Block
  49. :param block: Block
  50. :return:
  51. """ 
  52. # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
  53. block_string = json.dumps(block, sort_keys=True).encode()
  54. return hashlib.sha256(block_string).hexdigest()

上面的內(nèi)容簡單明了 —— 我添加了一些注釋和文檔字符串,以使代碼清晰可讀。到此為止,表示我們的區(qū)塊鏈基本上要完成了。但是,你肯定想知道新區(qū)塊是如何被創(chuàng)建、打造或者挖礦的。 

理解工作量證明

工作量證明Proof of Work(PoW)算法是在區(qū)塊鏈上創(chuàng)建或者挖出新區(qū)塊的方法。PoW 的目標(biāo)是去撞出一個能夠解決問題的數(shù)字。這個數(shù)字必須滿足“找到它很困難但是驗證它很容易”的條件 —— 網(wǎng)絡(luò)上的任何人都可以計算它。這就是 PoW 背后的核心思想。

我們來看一個非常簡單的示例來幫助你了解它。

我們來解決一個問題,一些整數(shù) x 乘以另外一個整數(shù) y 的結(jié)果的哈希值必須以 0 結(jié)束。因此,hash(x * y) = ac23dc…0。為簡單起見,我們先把 x = 5 固定下來。在 Python 中的實現(xiàn)如下:

 
 
 
 
  1. from hashlib import sha256 
  2. x = 5
  3. y = 0 # We don't know what y should be yet... 
  4. while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":
  5. y += 1 
  6. print(f'The solution is y = {y}')

在這里的答案是 y = 21。因為它產(chǎn)生的哈希值是以 0 結(jié)尾的:

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

在比特幣中,工作量證明算法被稱之為 Hashcash。與我們上面的例子沒有太大的差別。這就是礦工們進(jìn)行競賽以決定誰來創(chuàng)建新塊的算法。一般來說,其難度取決于在一個字符串中所查找的字符數(shù)量。然后礦工會因其做出的求解而得到獎勵的幣——在一個交易當(dāng)中。

網(wǎng)絡(luò)上的任何人都可以很容易地去核驗它的答案。 

實現(xiàn)基本的 PoW

為我們的區(qū)塊鏈來實現(xiàn)一個簡單的算法。我們的規(guī)則與上面的示例類似:

找出一個數(shù)字 p,它與前一個區(qū)塊的答案進(jìn)行哈希運算得到一個哈希值,這個哈希值的前四位必須是由 0 組成。

 
 
 
 
  1. import hashlib
  2. import json 
  3. from time import time
  4. from uuid import uuid4 
  5. class Blockchain(object):
  6. ... 
  7. def proof_of_work(self, last_proof):
  8. """
  9. Simple Proof of Work Algorithm:
  10. - Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
  11. - p is the previous proof, and p' is the new proof
  12. :param last_proof:
  13. :return:
  14. """ 
  15. proof = 0
  16. while self.valid_proof(last_proof, proof) is False:
  17. proof += 1 
  18. return proof 
  19. @staticmethod
  20. def valid_proof(last_proof, proof):
  21. """
  22. Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes?
  23. :param last_proof: Previous Proof
  24. :param proof: Current Proof
  25. :return: True if correct, False if not.
  26. """ 
  27. guess = f'{last_proof}{proof}'.encode()
  28. guess_hash = hashlib.sha256(guess).hexdigest()
  29. return guess_hash[:4] == "0000"

為了調(diào)整算法的難度,我們可以修改前導(dǎo) 0 的數(shù)量。但是 4 個零已經(jīng)足夠難了。你會發(fā)現(xiàn),將前導(dǎo) 0 的數(shù)量每增加一,那么找到正確答案所需要的時間難度將大幅增加。

我們的類基本完成了,現(xiàn)在我們開始去使用 HTTP 請求與它交互。 

第 2 步:以 API 方式去訪問我們的區(qū)塊鏈

我們將使用 Python Flask 框架。它是個微框架,使用它去做端點到 Python 函數(shù)的映射很容易。這樣我們可以使用 HTTP 請求基于 web 來與我們的區(qū)塊鏈對話。

我們將創(chuàng)建三個方法:

  • /transactions/new 在一個區(qū)塊上創(chuàng)建一個新交易
  • /mine 告訴我們的服務(wù)器去挖礦一個新區(qū)塊
  • /chain 返回完整的區(qū)塊鏈 

配置 Flask

我們的 “服務(wù)器” 將在我們的區(qū)塊鏈網(wǎng)絡(luò)中產(chǎn)生一個單個的節(jié)點。我們來創(chuàng)建一些樣板代碼:

 
 
 
 
  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. class Blockchain(object):
  8. ...  
  9. # Instantiate our Node
  10. app = Flask(__name__) 
  11. # Generate a globally unique address for this node
  12. node_identifier = str(uuid4()).replace('-', '') 
  13. # Instantiate the Blockchain
  14. blockchain = Blockchain()  
  15. @app.route('/mine', methods=['GET'])
  16. def mine():
  17. return "We'll mine a new Block" 
  18. @app.route('/transactions/new', methods=['POST'])
  19. def new_transaction():
  20. return "We'll add a new transaction" 
  21. @app.route('/chain', methods=['GET'])
  22. def full_chain():
  23. response = {
  24. 'chain': blockchain.chain,
  25. 'length': len(blockchain.chain),
  26. }
  27. return jsonify(response), 200 
  28. if __name__ == '__main__':
  29. app.run(host='0.0.0.0', port=5000)

對上面的代碼,我們做添加一些詳細(xì)的解釋:

  • Line 15:實例化我們的節(jié)點。更多關(guān)于 Flask 的知識讀 這里。
  • Line 18:為我們的節(jié)點創(chuàng)建一個隨機(jī)的名字。
  • Line 21:實例化我們的區(qū)塊鏈類。
  • Line 24–26:創(chuàng)建 /mine 端點,這是一個 GET 請求。
  • Line 28–30:創(chuàng)建 /transactions/new 端點,這是一個 POST 請求,因為我們要發(fā)送數(shù)據(jù)給它。
  • Line 32–38:創(chuàng)建 /chain 端點,它返回全部區(qū)塊鏈。
  • Line 40–41:在 5000 端口上運行服務(wù)器。 

交易端點

這就是對一個交易的請求,它是用戶發(fā)送給服務(wù)器的:

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

因為我們已經(jīng)有了添加交易到塊中的類方法,剩下的就很容易了。讓我們寫個函數(shù)來添加交易:

 
 
 
 
  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, jsonify, request 
  7. ... 
  8. @app.route('/transactions/new', methods=['POST'])
  9. def new_transaction():
  10. values = request.get_json() 
  11. # Check that the required fields are in the POST'ed data
  12. required = ['sender', 'recipient', 'amount']
  13. if not all(k in values for k in required):
  14. return 'Missing values', 400 
  15. # Create a new Transaction
  16. index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount']) 
  17. response = {'message': f'Transaction will be added to Block {index}'}
  18. return jsonify(response), 201

創(chuàng)建交易的方法 

挖礦端點

我們的挖礦端點是見證奇跡的地方,它實現(xiàn)起來很容易。它要做三件事情:

  1. 計算工作量證明
  2. 因為礦工(我們)添加一個交易而獲得報酬,獎勵礦工(我們) 1 個幣
  3. 通過將它添加到鏈上而打造一個新區(qū)塊
 
 
 
 
  1. import hashlib
  2. import json 
  3. from time import time
  4. from uuid import uuid4 
  5. from flask import Flask, jsonify, request 
  6. ... 
  7. @app.route('/mine', methods=['GET'])
  8. def mine():
  9. # We run the proof of work algorithm to get the next proof...
  10. last_block = blockchain.last_block
  11. last_proof = last_block['proof']
  12. proof = blockchain.proof_of_work(last_proof) 
  13. # We must receive a reward for finding the proof.
  14. # The sender is "0" to signify that this node has mined a new coin.
  15. blockchain.new_transaction(
  16. sender="0",
  17. recipient=node_identifier,
  18. amount=1,
  19. ) 
  20. # Forge the new Block by adding it to the chain
  21. previous_hash = blockchain.hash(last_block)
  22. block = blockchain.new_block(proof, previous_hash) 
  23. response = {
  24. 'message': "New Block Forged",
  25. 'index': block['index'],
  26. 'transactions': block['transactions'],
  27. 'proof': block['proof'],
  28. 'previous_hash': block['previous_hash'],
  29. }
  30. return jsonify(response), 200

注意,挖掘出的區(qū)塊的接收方是我們的節(jié)點地址?,F(xiàn)在,我們所做的大部分工作都只是與我們的 Blockchain 類的方法進(jìn)行交互的。到目前為止,我們已經(jīng)做完了,現(xiàn)在開始與我們的區(qū)塊鏈去交互。 

第 3 步:與我們的區(qū)塊鏈去交互

你可以使用簡單的 cURL 或者 Postman 通過網(wǎng)絡(luò)與我們的 API 去交互。

啟動服務(wù)器:

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

我們通過生成一個 GET 請求到 http://localhost:5000/mine 去嘗試挖一個區(qū)塊:

使用 Postman 去生成一個 GET 請求

我們通過生成一個 POST 請求到 http://localhost:5000/transactions/new 去創(chuàng)建一個區(qū)塊,請求數(shù)據(jù)包含我們的交易結(jié)構(gòu):

使用 Postman 去生成一個 POST 請求

如果你不使用 Postman,也可以使用 cURL 去生成一個等價的請求:

 
 
 
 
  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"

我重啟動我的服務(wù)器,然后我挖到了兩個區(qū)塊,這樣總共有了 3 個區(qū)塊。我們通過請求 http://localhost:5000/chain 來檢查整個區(qū)塊鏈:

 
 
 
 
  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
  38. } 

第 4 步:共識

這是很酷的一個地方。我們已經(jīng)有了一個基本的區(qū)塊鏈,它可以接收交易并允許我們?nèi)ネ诰虺鲂聟^(qū)塊。但是區(qū)塊鏈的整個重點在于它是去中心化的decentralized。而如果它們是去中心化的,那我們?nèi)绾尾拍艽_保它們表示在同一個區(qū)塊鏈上?這就是共識Consensus問題,如果我們希望在我們的網(wǎng)絡(luò)上有多于一個的節(jié)點運行,那么我們將必須去實現(xiàn)一個共識算法。 

注冊新節(jié)點

在我們能實現(xiàn)一個共識算法之前,我們需要一個辦法去讓一個節(jié)點知道網(wǎng)絡(luò)上的鄰居節(jié)點。我們網(wǎng)絡(luò)上的每個節(jié)點都保留有一個該網(wǎng)絡(luò)上其它節(jié)點的注冊信息。因此,我們需要更多的端點:

  1. /nodes/register 以 URL 的形式去接受一個新節(jié)點列表
  2. /nodes/resolve 去實現(xiàn)我們的共識算法,由它來解決任何的沖突 —— 確保節(jié)點有一個正確的鏈。

我們需要去修改我們的區(qū)塊鏈的構(gòu)造函數(shù),來提供一個注冊節(jié)點的方法:

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

一個添加鄰居節(jié)點到我們的網(wǎng)絡(luò)的方法

注意,我們將使用一個 set() 去保存節(jié)點列表。這是一個非常合算的方式,它將確保添加的節(jié)點是冪等idempotent的 —— 這意味著不論你將特定的節(jié)點添加多少次,它都是精確地只出現(xiàn)一次。 

實現(xiàn)共識算法

正如前面提到的,當(dāng)一個節(jié)點與另一個節(jié)點有不同的鏈時就會產(chǎn)生沖突。為解決沖突,我們制定一個規(guī)則,即最長的有效的鏈才是權(quán)威的鏈。換句話說就是,網(wǎng)絡(luò)上最長的鏈就是事實上的區(qū)塊鏈。使用這個算法,可以在我們的網(wǎng)絡(luò)上節(jié)點之間達(dá)到共識。

 
 
 
 
  1. ...
  2. import requests  
  3. class Blockchain(object)
  4. ... 
  5. def valid_chain(self, chain):
  6. """
  7. Determine if a given blockchain is valid
  8. :param chain: A blockchain
  9. :return: True if valid, False if not
  10. """ 
  11. last_block = chain[0]
  12. current_index = 1 
  13. while current_index < len(chain):
  14. block = chain[current_index]
  15. print(f'{last_block}')
  16. print(f'{block}')
  17. print("\n-----------\n")
  18. # Check that the hash of the block is correct
  19. if block['previous_hash'] != self.hash(last_block):
  20. return False 
  21. # Check that the Proof of Work is correct
  22. if not self.valid_proof(last_block['proof'], block['proof']):
  23. return False 
  24. last_block = block
  25. current_index += 1 
  26. return True 
  27. def resolve_conflicts(self):
  28. """
  29. This is our Consensus Algorithm, it resolves conflicts
  30. by replacing our chain with the longest one in the network.
  31. :return: True if our chain was replaced, False if not
  32. """ 
  33. neighbours = self.nodes
  34. new_chain = None 
  35. # We're only looking for chains longer than ours
  36. max_length = len(self.chain) 
  37. # Grab and verify the chains from all the nodes in our network
  38. for node in neighbours:
  39. response = requests.get(f'http://{node}/chain') 
  40. if response.status_code == 200:
  41. length = response.json()['length']
  42. chain = response.json()['chain'] 
  43. # Check if the length is longer and the chain is valid
  44. if length > max_length and self.valid_chain(chain):
  45. max_length = length
  46. new_chain = chain 
  47. # Replace our chain if we discovered a new, valid chain longer than ours
  48. if new_chain:
  49. self.chain = new_chain
  50. return True 
  51. return False

第一個方法 valid_chain() 是負(fù)責(zé)來檢查鏈?zhǔn)欠裼行?,它通過遍歷區(qū)塊鏈上的每個區(qū)塊并驗證它們的哈希和工作量證明來檢查這個區(qū)塊鏈?zhǔn)欠裼行А?/p>

resolve_conflicts() 方法用于遍歷所有的鄰居節(jié)點,下載它們的鏈并使用上面的方法去驗證它們是否有效。如果找到有效的鏈,確定誰是最長的鏈,然后我們就用最長的鏈來替換我們的當(dāng)前的鏈。

在我們的 API 上來注冊兩個端點,一個用于添加鄰居節(jié)點,另一個用于解決沖突:

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

這種情況下,如果你愿意,可以使用不同的機(jī)器來做,然后在你的網(wǎng)絡(luò)上啟動不同的節(jié)點?;蛘呤窃谕慌_機(jī)器上使用不同的端口啟動另一個進(jìn)程。我是在我的機(jī)器上使用了不同的端口啟動了另一個節(jié)點,并將它注冊到了當(dāng)前的節(jié)點上。因此,我現(xiàn)在有了兩個節(jié)點:http://localhost:5000http://localhost:5001

注冊一個新節(jié)點

我接著在節(jié)點 2 上挖出一些新區(qū)塊,以確保這個鏈?zhǔn)亲铋L的。之后我在節(jié)點 1 上以 GET 方式調(diào)用了 /nodes/resolve,這時,節(jié)點 1 上的鏈被共識算法替換成節(jié)點 2 上的鏈了:

工作中的共識算法

然后將它們封裝起來 … 找一些朋友來幫你一起測試你的區(qū)塊鏈。


我希望以上內(nèi)容能夠鼓舞你去創(chuàng)建一些新的東西。我是加密貨幣的狂熱擁護(hù)者,因此我相信區(qū)塊鏈將迅速改變我們對經(jīng)濟(jì)、政府和記錄保存的看法。

更新: 我正計劃繼續(xù)它的第二部分,其中我將擴(kuò)展我們的區(qū)塊鏈,使它具備交易驗證機(jī)制,同時討論一些你可以在其上產(chǎn)生你自己的區(qū)塊鏈的方式。(LCTT 譯注:第二篇并沒有~?。?/p>
網(wǎng)站題目:想學(xué)習(xí)區(qū)塊鏈?那就用Python構(gòu)建一個
標(biāo)題鏈接:http://www.5511xx.com/article/djhdjgc.html