经过构建一个区块链应用来学习区块链!

本文首发于万向区块链旗下“万云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,此处的链已经被共识算法计算后的获得的新链所替代。

 

如今,你能够邀请一些朋友来一块儿测试你的区块链了。

 

本文教程到此结束,那么,属于你本身的区块链撸好了吗?别忘了分享给身边同为程序员的朋友,一块儿来撸区块链!

相关文章
相关标签/搜索