經過構建一個區塊鏈應用來學習區塊鏈!

本文首發於萬向區塊鏈旗下「萬雲Wancloud」微信公衆號。node

2018年的門剛打開,區塊鏈的火就燒成了火焰山。徐小平放言要擁抱區塊鏈,朋友圈刷屏不止,連上班地鐵上都能聽到區塊鏈,一晚上起,區塊鏈成了茶前飯後的談資。因而乎,那個常常聽到的問題又開始抓耳撓腮:區塊鏈究竟是什麼鬼?關注的訂閱號不停推送「一篇文章讓你搞懂區塊鏈」,「三分鐘Get區塊鏈」等不盡相同的內容,聲音從四面八方聚焦到你耳邊。python

萬雲也在思考能爲想了解區塊鏈的老鐵們作點什麼,鑑於已有如此多區塊鏈概念普及文,這次咱們不聊枯燥的概念,而是迴歸區塊鏈「技術」,一步步認真教你得到一個屬於本身區塊鏈。放心,只要你稍微懂一點技術,你就能夠實現並擁有它。git

 

|| 如下翻譯自Daniel van Flymen的《Learn Blockchains by Building One》,有所刪改。程序員

|| 原文地址:https://hackernoon.com/learn-blockchains-by-building-one-117428612f46github

 

前言

概念瞭解:在開始前你須要知道,區塊鏈是一種按時間將數據區塊以順序相連的方式組合在一塊兒的鏈式數據結構,並經過密碼學來保證其不可篡改和不可僞造的分佈式帳本。這些區塊能夠包含交易、文件以及任何你想要的數據,重要的是它們經過哈希連接在一塊兒。web

目標讀者:能夠輕鬆地閱讀和編寫一些基本的Python,而且對HTTP有一些瞭解。算法

所需工具:Python 3.6+、Flask、Requests:後端

pip install Flask==0.12.2 requests==2.18.4服務器

除此以外還需安裝HTTP工具,如Postman、cURL。微信

源代碼地址https://github.com/dvf/blockchain

 

第一步:創建區塊鏈

①實現一個Blockchain類

打開一個你經常使用的文本編輯器或者IDE,新建一個blockchain.py的python文件,並建立一個Blockchain類,在構造函數中建立兩個空的隊列,一個用於存儲區塊鏈,另外一個用於存儲交易。下面是Blockchain類的模板代碼:

 

咱們所建立的Blockchain類將用來管理鏈,它會存儲交易,而且提供一些方法來幫助添加新的區塊到鏈。下面是詳細的實現方法。

每一個區塊所包含5個基本屬性:index,timestamp (in Unix time),交易列表,工做量證實和前一個區塊的哈希值。咱們來看一個例子:

 

到這裏,咱們對於鏈的概念應該比較清楚了,每一個新的區塊都會包含上一個區塊的哈希值,從而讓區塊鏈具備不可篡改的特性。若是攻擊者攻擊了鏈中比較靠前的區塊,則全部後面的區塊將包含不正確的哈希值。若是不能理解,慢慢消化——這是理解區塊鏈技術的核心思想。

 

②將交易添加到區塊

接下來咱們實現一個將交易添加到區塊的方法,繼續看代碼:

 

在new_transaction()方法中向列表中添加一筆交易以後,它返回值是本次交易的index,該index會被添加到下一個待挖掘區塊,後面在用戶提交交易時也會用到。

 

③建一個新的區塊

當Blockchain被實例化後,咱們須要建立一個創世區塊,同時爲咱們的創世區塊添加一個工做量證實,這是挖礦的結果,咱們稍後會詳細討論挖礦。

除了建立創世區塊的代碼,咱們還須要補充new_block(),new_transaction()和hash()的方法:

 

到此,咱們的區塊鏈已經基本上實現了雛形。這時候,你確定想知道新區塊是怎麼被挖出來的,也就是咱們一般所說的「挖礦」。

 

④什麼是工做量證實?

想了解什麼是「挖礦」,就必須理解工做量證實(POW)是什麼。區塊鏈上每個新的區塊都來自於工做量證實(POW),POW的目標是計算出一串解決問題的數字,這個結果衆所周知是很難計算的,但卻十分容易驗證,由於網絡上的任何人都可以驗證這個結果,這是「工做量證實」背後的核心思想。

咱們來看一個很是簡單的例子幫助理解:

假設整數X乘以另外一個整數y的哈希值必須以0結尾,hash(x * y) = ac23dc...0. 設x = 5.求y。咱們用Python來實現:

 

獲得的答案是當y = 21,哈希值的結尾爲0:

 

在比特幣中,工做證實算法被稱爲Hashcash,這和咱們上面所舉的例子差很少,結果難於發現卻易於校驗。Hashcash是礦工爲了建立一個新區塊而爭相計算的問題,計算難度一般取決於字符串中搜索的字符數,一般也會花費必定的時間才能計算獲得,最終計算出來的礦工們會經過交易得到必定數量的比特幣做爲獎勵。

 

⑤實現一個基本的工做量證實

首先咱們爲Blockchain類實現一個相似的算法:

規則:找到一個數字p,使得它與前一個區塊的 proof 拼接成的字符串的 Hash 值以 4 個零開頭。

 

經過修改前導零的數量,能夠調整算法的難度,可是4個零徹底足夠了。你會發現,每當增長一個前導零,找到一個對應的解決方案與所需的時間之間會產生巨大的差別。

進行到這裏,咱們的Blockchain類已經基本完成,接下來咱們實現HTTP服務進行交互。

 

第二步:區塊鏈API

咱們將使用Python Flask框架,Flask是一個輕量級的Web應用框架,這使咱們能夠經過web服務來調用Blockchian類。

 

①建立三個API:

•/ transactions / new爲區塊建立一個新的交易

•/mine告訴咱們的服務器開採新的區塊。

•/chain返回整個區塊鏈。

 

②使用Flask

咱們的「服務器」將基於Flask框架來實現區塊鏈網絡中的一個節點。 咱們來添加一些模板代碼:

 

如下是對上面添加的內容的進行簡要說明:

Line15:實例化Flask web服務節點。

Line18:爲咱們的服務節點建立一個隨機的名稱。

Line21:實例化Blockchain類。

Line24-26:建立一個路由爲/mine的GET請求的,調用後端Blockchain的new block方法。

Line28-30:建立一個路由爲/transactions/new的POST請求,將數據發送給後端Blockchina的new transaction方法。

Line32-38:建立一個路由爲/chain的GET請求,將返回整個鏈。

Line40-41:在端口5000上運行服務器。

 

③實現交易

下面是用戶發起交易時發送到服務器的請求:

 

因爲咱們已經有了將交易添加到區塊的方法,接下去就十分容易了。

下面咱們來實現添加交易的函數:

 

④實現挖礦

咱們的挖礦方法是魔法發生的地方。它十分容易,只作三件事情:計算工做量證實;經過新增一筆交易獎勵礦工必定數量的比特幣;建立新的區塊並將其添加到鏈中來。

 

須要注意的是,開採塊的交易接收者是咱們本身服務器節點的地址,咱們在這裏所作的大部分工做只是與Blockchain類進行交互,基於以上咱們區塊鏈已經完成了,接下來開始交互演示。

 

第三步:交互演示

您可使用cURL或Postman與API進行交互。

啓動服務器:

 

嘗試經過向http:// localhost:5000 / mine發出GET請求來挖掘區塊:

 

建立一個新的交易,向http://localhost:5000/transactions/new發出一個POST請求:

 

也可使用cURL發送請求:

 

以上僅爲交互演示的示例,你能夠在你本身所完成的區塊鏈上進行更多嘗試。

 

第四步:共識機制

咱們有一個基本的區塊鏈能夠進行交易和挖礦,但其實區塊鏈更重要的意義在於它們是分佈式的。那麼咱們須要確保全部的節點都運行在同一條鏈上,這就是迴歸到了共識問題,若是要知足在網絡上有多個節點而且不斷增長,咱們必需要實現共識算法。

 

①註冊新的節點

在實現共識算法以前,須要找到一種方式讓網絡上的節點知道其相鄰的節點,每一個節點都須要存儲網絡上其餘節點的記錄。所以,咱們須要新增幾個方法來幫助實現:

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

2. / nodes / resolve來執行咱們的共識算法,它能夠解決任何衝突,確保節點具備正確的鏈。

 下面咱們將修改Blockchain的構造函數以提供註冊節點的方法:

 

注意,咱們使用set()集合來保存節點列表,這是確保新節點的添加是冪等的簡便方法,這意味着不管咱們添加特定節點多少次,它都只會出現一次。

 

②實現共識算法

如前所述,當一個節點與另外一個節點有不一樣時會發生衝突,爲了解決這個問題,咱們遵循取最長鏈原則,經過使用此算法,讓網絡中的節點間達成共識。

 

valid_chain()負責檢查一個鏈是否有效,具體方法是循環讀取每一個區塊並驗證哈希和證實。

resolve_conflicts()負責循環讀取全部相鄰節點,獲取它們的鏈並使用上面的方法驗證它們的有效性。若是找到了一個更長的有效鏈,則取代咱們當前的鏈。

咱們將兩個方法註冊到咱們的API中,一個用於添加相鄰節點,另外一個用於解決衝突:

 

最後,若是你願意的話能夠開啓另外一臺機器,並在你的網絡上運轉不一樣的節點。或者使用同一臺機器上的不一樣端口啓動進程。我在個人機器的不一樣端口建立另一個節點,並將其註冊到當前區塊鏈網絡中。 所以,我有兩個節點:http:// localhost:5000和http:// localhost:5001。

 

爲了確保鏈更長,我在節點2上挖掘了一些新的區塊。 以後,我在節點1上調用GET / nodes / resolve,此處的鏈已經被共識算法計算後的獲得的新鏈所替代。

 

如今,你能夠邀請一些朋友來一塊兒測試你的區塊鏈了。

 

本文教程到此結束,那麼,屬於你本身的區塊鏈擼好了嗎?別忘了分享給身邊同爲程序員的朋友,一塊兒來擼區塊鏈!

相關文章
相關標籤/搜索