學習區(qū)塊鏈的最好方法是構建一個(下)
深入理解區(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)濟、政府和記錄保存的看法。
風險警示:藍狐所有文章都不構成投資推薦,投資有風險,建議對項目進行深入考察,慎重做好自己的投資決策。
相關閱讀
原文作者:Danielvan Flymen
原文地址:hackernoon.com
譯者:由藍狐筆記社群“iGreenMind”翻譯
本文由 @藍狐筆記社群“iGreenMind” 翻譯發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉載。
題圖來自 Pexels,基于 CC0 協(xié)議
很不錯,我一個開發(fā)的看了都覺得蠻清楚的