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

2 評論 3632 瀏覽 12 收藏 19 分鐘

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

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

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

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

啟動服務器:

1.? ??$?python?blockchain.py

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

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

UsingPostman to make a GET?request

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

UsingPostman to make a POST?request

如果你不使用 Postman 工具,同樣可以使用cURL這個工具來實現(xiàn)同樣的目的:

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”

重啟了我的服務器,并挖掘了兩個區(qū)塊,總共給出了3個區(qū)塊。讓我們通過請求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 接受交易,它允許我們挖掘新的區(qū)塊。但 Blockchain 的關鍵在于,它們應該是分布式的。如果它們是分布式的,我們?nèi)绾未_保它們都在一條鏈?這被稱為共識的問題,如果我們想要在我們的網(wǎng)絡中有多個節(jié)點,我們就必須實現(xiàn)一個共識的算法。

注冊新節(jié)點

在實現(xiàn)共識算法之前,我們需要一種方法讓節(jié)點知道網(wǎng)絡上的相鄰節(jié)點。我們網(wǎng)絡上的每個節(jié)點都應該保留網(wǎng)絡上其他節(jié)點的注冊表。因此,我們需要更多的端點:

1.?/nodes/register?以url的形式接受新的節(jié)點列表。

2.??/nodes/resolve?? 來實現(xiàn)我們的共識算法,它可以解決任何沖突——以確保一個節(jié)點擁有正確的鏈。

我們需要修改 Blockchain 的構造函數(shù),并提供注冊節(jié)點的方法:

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:?<str>?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()來保存節(jié)點列表。這是確保新節(jié)點的添加具有冪等性的廉價方式,這意味著無論我們添加多少次特定節(jié)點,它都只會出現(xiàn)一次。

實現(xiàn)算法的共識

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

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:?<list>?A?blockchain

13.??????????????????:return:?<bool>?True?if?valid,?False?if?not

14.??????????????????“””

15.

16.??????????????????last_block?=?chain[0]

17.??????????????????current_index?=?1

18.

19.??????????????????while?current_index?<?len(chain):

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:?<bool>?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() 負責檢查鏈是否有效,通過循環(huán)遍歷每個區(qū)塊并驗證哈希和證明。

resolve_conflicts() 是這么一個方法:它遍歷我們所有的鄰近節(jié)點,下載它們的鏈并使用上面的方法驗證它們。如果一個有效的鏈被發(fā)現(xiàn),它的長度大于我們的,我們就替換掉我們當前所使用的鏈。

讓我們將兩個端點注冊到API中,一個用于添加相鄰節(jié)點,另一個用于解決沖突:

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

此時,你可以使用不同的機器,并在網(wǎng)絡上創(chuàng)建不同的節(jié)點?;蛘咴谕慌_機器上使用不同的端口來啟動進程。我在我的機器上的另一個端口上啟動了另一個節(jié)點,并將它注冊到我當前的節(jié)點上。因此,我有兩個節(jié)點:? http://localhost:5000? 和 http://localhost:5001? 。

Registeringa new?Node

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

ConsensusAlgorithm at?Work

去找?guī)讉€朋友測試一下你的Blockchain吧。

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

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

相關閱讀

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

原文作者:Danielvan Flymen

原文地址:hackernoon.com

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

本文由 @藍狐筆記社群“iGreenMind” 翻譯發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉載。

題圖來自 Pexels,基于 CC0 協(xié)議

更多精彩內(nèi)容,請關注人人都是產(chǎn)品經(jīng)理微信公眾號或下載App
評論
評論請登錄
  1. 很不錯,我一個開發(fā)的看了都覺得蠻清楚的

    來自廣東 回復