酷播亮新聞
最棒的知識補給站

學習區塊鏈的最好方法是構建一個(下)

深入理解區塊鏈最好的方式莫過於親手搭建一個,在這個過程中理解它背後的邏輯和原理。

接上一篇《 學習區塊鏈的最好方法是構建一個(上)

第三步:與我們的區塊鏈交互

你可以使用普通的cURL或Postman工具,通過網絡與我們的API進行交互。

啟動服務器:

1.    $ python blockchain.py

2.     * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

讓我們嘗試通過向http://localhost:5000/mine發出GET請求來挖掘一個區塊:

UsingPostman to make a GET request

讓我們通過向http://localhost:5000/transactions/new  發出一個POST請求來創建一個新的交易,這個交易包含了交易結構的主體:

UsingPostman to make a POST request

如果你不使用 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”

重啟了我的服務器,並挖掘了兩個區塊,總共給出了3個區塊。 讓我們通過請求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

38.          }

第四步:共識

這非常酷。 我們有一個基本的 Blockchain 接受交易,它允許我們挖掘新的區塊。 但 Blockchain 的關鍵在於,它們應該是分佈式的。 如果它們是分佈式的,我們如何確保它們都在一條鏈? 這被稱為共識的問題,如果我們想要在我們的網絡中有多個節點,我們就必須實現一個共識的算法。

註冊新節點

在實現共識算法之前,我們需要一種方法讓節點知道網絡上的相鄰節點。 我們網絡上的每個節點都應該保留網絡上其他節點的註冊表。 因此,我們需要更多的端點:

1. /nodes/register 以url的形式接受新的節點列表。

2.  /nodes/resolve   來實現我們的共識算法,它可以解決任何衝突——以確保一個節點擁有正確的鏈。

我們需要修改 Blockchain 的構造函數,並提供註冊節點的方法:

1.             …

2.             from urllib.parse import urlparse

3.             …

4.

5.

6.             class Blockchain(object):

7.                 def __init__(self):

8.                     …

9.                     self.nodes = set()

10.                  …

11.

12.              def register_node(self, address):

13.                  “””

14.                  Add a new node to the list of nodes

15.

16.                  :param address:   Address of node. Eg. ‘http://192.168.0.5:5000’

17.                  :return: None

18.                  “””

19.

20.                  parsed_url = urlparse(address)

21.                  self.nodes.add(parsed_url.netloc)

Amethod for adding neighbouring nodes to our Network

使用set()來保存節點列表。 這是確保新節點的添加具有冪等性的廉價方式,這意味著無論我們添加多少次特定節點,它都只會出現一次。

實現算法的共識

如前所述,當一個節點與另一個節點具有不同鏈時就有了衝突。 為了解決這個問題,我們制定一條規則:最長的並且有效的鏈才是權威的。 換句話說,網絡上最長的鍊是事實上的鏈。 利用該算法,我們在網絡節點之間達成了一致。

1.             …

2.             import requests

3.

4.

5.             class Blockchain(object)

6.                 …

7.

8.                 def valid_chain(self, chain):

9.                     “””

10.                  Determine if a given blockchain is valid

11.

12.                  :param chain:   A blockchain

13.                  :return:   True if valid, False if not

14.                  “””

15.

16.                  last_block = chain[0]

17.                  current_index = 1

18.

19.                  while current_index 

20.                      block = chain[current_index]

21.                      print(f'{last_block}’)

22.                      print(f'{block}’)

23.                      print(“n———–n”)

24.                      # Check that the hash of the block is correct

25.                      if block[‘previous_hash’] != self.hash(last_block):

26.                          return False

27.

28.                      # Check that the Proof of Work is correct

29.                      if not self.valid_proof(last_block[‘proof’], block[‘proof’]):

30.                          return False

31.

32.                      last_block = block

33.                      current_index += 1

34.

35.                  return True

36.

37.              def resolve_conflicts(self):

38.                  “””

39.                  This is our Consensus Algorithm, it resolves conflicts

40.                  by replacing our chain with the longest one in the network.

41.

42.                  :return:   True if our chain was replaced, False if not

43.                  “””

44.

45.                  neighbours = self.nodes

46.                  new_chain = None

47.

48.                  # We’re only looking for chains longer than ours

49.                  max_length = len(self.chain)

50.

51.                  # Grab and verify the chains from all the nodes in our network

52.                  for node in neighbours:

53.                      response = requests.get(f’http://{node}/chain’)

54.

55.                      if response.status_code == 200:

56.                          length = response.json()[‘length’]

57.                          chain = response.json()[‘chain’]

58.

59.                          # Check if the length is longer and the chain is valid

60.                          if length > max_length and self.valid_chain(chain):

61.                              max_length = length

62.                              new_chain = chain

63.

64.                  # Replace our chain if we discovered a new, valid chain longer than ours

65.                  if new_chain:

66.                      self.chain = new_chain

67.                      return True

68.

69.                  return False

第一個方法valid_chain() 負責檢查鍊是否有效,通過循環遍歷每個區塊並驗證哈希和證明。

resolve_conflicts() 是這麼一個方法:它遍歷我們所有的鄰近節點,下載它們的鏈並使用上面的方法驗證它們。 如果一個有效的鏈被發現,它的長度大於我們的,我們就替換掉我們當前所使用的鏈。

讓我們將兩個端點註冊到API中,一個用於添加相鄰節點,另一個用於解決衝突:

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.

19.          @app.route(‘/nodes/resolve’, methods=[‘GET’])

20.          def consensus():

21.              replaced = blockchain.resolve_conflicts()

22.

23.              if replaced:

24.                  response = {

25.                      ‘message’: ‘Our chain was replaced’,

26.                      ‘new_chain’: blockchain.chain

27.                  }

28.              else:

29.                  response = {

30.                      ‘message’: ‘Our chain is authoritative’,

31.                      ‘chain’: blockchain.chain

32.                  }

33.

34.              return jsonify(response), 200

此時,你可以使用不同的機器,並在網絡上創建不同的節點。 或者在同一台機器上使用不同的端口來啟動進程。 我在我的機器上的另一個端口上啟動了另一個節點,並將它註冊到我當前的節點上。 因此,我有兩個節點:  http://localhost:5000  和 http://localhost:5001  。

Registeringa new Node

然後我在節點2上挖掘了一些新的區塊,以確保鏈更長。 之後,我在節點1上調用 GET /nodes/resolve  ,在節點1上的鏈被共識算法所取代:

ConsensusAlgorithm at Work

去找幾個朋友測試一下你的Blockchain吧。

我希望這能激勵你去創造一些新的東西。 我對加密貨幣感到興奮,因為我相信區塊鏈會迅速改變我們對經濟、政府和記錄保存的看法。

風險警示: 藍狐所有文章都不構成投資推薦,投資有風險,建議對項目進行深入考察,慎重做好自己的投資決策。

相關閱讀

學習區塊鏈的最好方法是構建一個(上)

原文作者:Danielvan Flymen

原文地址:hackernoon.com

譯者:由藍狐筆記社群“iGreenMind”翻譯

本文由 @藍狐筆記社群“iGreenMind” 翻譯發佈於人人都是產品經理。 未經許可,禁止轉載。

題圖來自 Pexels,基於 CC0 協議

如有侵權請來信告知:酷播亮新聞 » 學習區塊鏈的最好方法是構建一個(下)