为了账号安全,请及时绑定邮箱和手机立即绑定

动手建区块链,边学边用通俗易懂!

如果你想最快地了解区块链是怎么工作的,那就自己动手建一个吧。

你来这里是因为,和我一样,你对加密货币的崛起非常激动。你想知道区块链的工作原理——支撑它们的核心技术。

但这并不容易——至少对我来说。我艰难地观看了一堆密集的视频,跟着零散的教程摸索,因为缺少例子而倍感沮丧。

我喜欢通过实践来学习。这迫使我在代码层面处理相关内容,使知识更牢固地扎根。如果你也这么做,在完成本指南时,你将拥有一个功能完整的区块链,并能深刻理解它们的工作原理。

在你开始之前,请先看看下面的提示…

记住,区块链是一个不可变且按顺序排列的记录链,这些记录被称为区块。每个区块可以包含交易、文件或任何你想要的数据。但,重要的是,它们是通过哈希值链接在一起的。

如果你还不知道什么是哈希值,你可以在这里找到解释:这里有一个解释

这份指南面向谁? 你需要能舒服地读写一些基本的Python代码,并且了解一些HTTP请求的基本知识,因为我们将会用HTTP与我们的区块链互动。

我需要什么? 确保安装了 Python 3.6(包括 pip 在内)。你还需要安装 Flask 和强大的 Requests 库:

你可以通过pip来安装指定版本的Flask和requests库,版本号分别是0.12.2和2.18.4:

pip install Flask==0.12.2 requests==2.18.4 

哦,你还需要一个HTTP客户端,比如Postman或cURL,任何工具都行。

最终代码在哪? 源代码可以在这里找到:[[available here](https://github.com/dvf/blockchain)]。

第一步:构建区块链

打开你最喜欢的文本编辑器或IDE,比如我个人最喜欢 ❤️ PyCharm。创建一个新的文件,命名为 blockchain.py。我们将只使用一个文件,如果你感到困惑,可以随时查看 源代码

区块链的表示

我们将创建一个 Blockchain 类,其构造函数会初始化一个初始为空的列表(用于存储区块),以及另一个列表用于存储交易。这就是我们类的设计蓝图。

区块链课的蓝图

我们的Blockchain类(以下简称区块链类)负责管理区块链。它将用来存储交易,并提供一些辅助方法来添加新的区块到区块链中。让我们开始实现一些方法。

一个区块长什么样?

每个区块都有一个 索引 ,一个 时间戳 (以 Unix 时间表示),一个 交易列表 ,一个 证明 (稍后讨论),以及 上一个区块的哈希

下面是一个单个区块的示例:

这是我们区块链中的一个区块示例。

此时,链的概念应该已经很明显了——每个新块都包含它前一个块的哈希。这一点至关重要,因为它正是区块链不可变性的基础:如果攻击者篡改了链中的某个早期区块,那么所有后续区块的哈希都会受影响。

这说得通吗?如果还摸不着头脑,花点时间琢磨琢磨,这正是区块链的核心理念。

将交易添加到区块

我们需要一种方法将交易添加到区块中。我们的 new_transaction() 方法负责这一点,这非常简单。

new_transaction() 在添加交易到列表后,它将返回交易将被添加到的 区块的位置索引即将被挖掘的下一个区块的索引。这对于提交交易的用户来说非常有用。

创建新区块

当我们实例化我们的Blockchain时,我们需要用一个_创世区块来初始化它,这个区块没有前驱。我们还需要在这个创世区块里加入一个“证明”_,这是通过挖矿(或工作量证明)得到的结果。我们之后会更详细地讨论挖矿。

除了在构造函数中创建_创世_区块外,我们还将实现和定义 new_block()new_transaction()hash() 方法。

以上应该非常直观——我添加了一些注释和_docstrings_来帮助保持清晰。我们几乎完成了区块链。这时,你可能在想,新的区块是怎么被创建、生成或挖矿(mining)的。

理解工作证明

工作量证明(PoW)算法是区块链上新区块如何被创建或 挖掘 的方式。PoW 的目的是找到一个能解决问题的数字。这个数字必须 很难找到但容易验证 ——从计算的角度来看——网络上的任何人都可以轻松验证。这就是工作量证明的核心思想。

我们来举个特别简单的例子,帮助大家理解得更透彻。

我们假设一些整数 x 乘以另一个 yhash哈希 必须以 0 结尾,也就是说,hash(x * y) = ac23dc...0。对于这个简化示例,我们将 x 设为 5。在 Python 中实现这个例子:

from hashlib import sha256

x = 5
y = 0  # 我们还不知道 y 应该是多少,先试试看...
while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0" :
    y += 1

print(f'最后的答案是 y = {y}')

这里 y = 21 是解决方案,因为生成的哈希值以 0 结尾,所以。

5 乘以 21 的哈希值是 1253e9373e...5e3600155e860

在比特币网络中,工作量证明算法称为Hashcash。它与我们上面提到的基本示例很相似。它是矿工们竞相解决以创建新区块的算法。一般来说,难度由在字符串中找到特定字符序列的难度决定的。矿工会因找到解决方案而获得一枚硬币作为奖励,通过一次交易接收奖励。

网络能够轻松验证他们的答案。

实现基本的工作量证明机制

让我们为我们的区块链实现一个类似的算法。为我们的区块链,我们的规则也将类似于上面的例子。

找到一个数 p ,将它与上一个区块的哈希值一起哈希时,产生一个以四个0开头的哈希值

为了调节算法的难度,我们可以修改前导零的个数。但4个前导零已经足够。你会发现,增加一个前导零会让找到解决方案所需的时间显著增加。

我们这个班级快要结束了,我们准备开始用HTTP请求与这个系统进行互动操作了。

第二步:我们的区块链API

我们将使用Python Flask微框架。这是一个微框架,这使得将端点映射到Python函数变得十分简单。这使我们能够通过HTTP请求与我们的区块链进行通信。

我们会创建三个方法。

  • /transactions/new 用于创建一个新的交易并添加到区块中
  • /mine 用于告诉我们的服务器挖出一个新的区块。
  • /chain 用于返回完整的区块链信息。
搭建 Flask 环境

我们的“节点”将在我们的区块链系统中形成一个节点。我们来创建一些基本代码。

简单说一下我们在上面加了什么

  • 第15行: 实例化我们的Node。更多关于Flask的信息可以在这里查看。
  • 第18行: 生成我们节点的随机名称。
  • 第21行: 实例化我们的Blockchain类。
  • 第24–26行: 这接收一个GET请求的/mine端点。
  • 第28–30行: 创建一个接收POST请求的/transactions/new端点,因为我们将通过该端点发送数据。
  • 第32–38行: 创建一个返回整个区块链数据的/chain端点。
  • 第40–41行: 启动服务器并在端口5000上运行。
交易接口

下面是一个交易请求消息的示例。用户会把这样的信息发送给服务器:

{
     "sender": "我方地址",
     "recipient": "对方地址",
     "amount": 5
}

因为我们已经有了向区块添加交易的方法,剩下的就容易多了。我们来写一个添加交易的函数吧。

如何创建交易的步骤

挖矿端口

我们的挖矿端点很容易,只需要做三件事。

  1. 计算工作量证明
  2. 通过给矿工(也就是我们)添加一个奖励1个币的交易来进行奖励
  3. 将新区块添加到链上

需要注意的是,挖矿得到的区块的接收者是这个地址,这个地址是我们的节点地址。我们在这里主要做的工作只是调用我们Blockchain类中的方法。到这个时候,我们已经完成了这些步骤,就可以开始和我们的区块链打交道了。

步骤三:与我们的区块链互动

你可以通过普通的 cURL 或 Postman 工具与我们的 API 进行网络互动操作。

启动服务器。

    $ python blockchain.py*, 启动在 <http://127.0.0.1:5000/> 运行中 (按 CTRL+C 终止)

让我们试试通过向 http://localhost:5000/mine 发送一个 GET 请求来挖掘一个区块

使用 Postman 发送一个 GET 请求

让我们通过向http://localhost:5000/transactions/new发送一个POST请求来创建一个新的交易记录,其中请求体包含我们的交易结构信息:

使用 Postman 发起一个 POST 请求

如果没有使用 Postman,你可以用 cURL 发出类似的请求:

    $ curl -X POST -H "Content-Type: application/json" -d ' {  
     "sender": "d4ee26eee15148ee92c6cd394edd974e",  
     "recipient": "someone-other-address",  
     "amount": 5  
    }' http://localhost:5000/transactions/new

我重新启动了我的服务器,并挖到了两个区块,总计三个区块。让我们通过请求 [http://localhost:5000/chain](http://localhost:5000/chain:) 检查整个区块链。

{
  "链": [  
    {  
      "区块索引": 1,  
      "前一区块哈希": 1,  
      "工作量证明": 100,  
      "时间戳": 1506280650.770839,  
      "交易": []  
    },  
    {  
      "区块索引": 2,  
      "前一区块哈希": "c099bc...bfb7",  
      "工作量证明": 35293,  
      "时间戳": 1506280664.717925,  
      "交易": [  
        {  
          "金额": 1,  
          "接收方": "8bbcb347e0634905b0cac7955bae152b",  
          "发送方": "0"  
        }  
      ]  
    },  
    {  
      "区块索引": 3,  
      "前一区块哈希": "eff91a...10f2",  
      "工作量证明": 35089,  
      "时间戳": 1506280666.1086972,  
      "交易": [  
        {  
          "金额": 1,  
          "接收方": "8bbcb347e0634905b0cac7955bae152b",  
          "发送方": "0"  
        }  
      ]  
    }  
  ],  
  "长度": 3  
}
步骤 4:达成共识

这真的很酷!我们有一个基本的区块链,可以接受交易,并让我们能够挖出新的区块。但区块链的关键在于它们应该是去中心化的。但如果它们是去中心化的,我们又怎么保证它们都是一条链呢?这就是所谓的共识难题,如果我们想要网络中有多个节点,我们就得实现一个共识算法。

注册新节点

在我们能够实施一个共识算法之前,我们需要一种方式让一个节点能够找到网络上的邻近节点。每个节点都应该记录下网络上的其他节点。因此,所以我们需要一些额外的接口或端点。

  1. /nodes/register 用于接收一系列以 URL 格式表示的新节点。
  2. /nodes/resolve 用于实现我们的共识算法(Consensus Algorithm),解决可能出现的任何冲突,以确保节点拥有正确的区块链。

我们需要修改我们区块链的构造函数,并提供一种注册节点的方法。

将邻近节点添加到我们网络中的方法

注意,我们使用了 set() 来存放节点。这是一种低成本的方法,确保每次添加新节点都是幂等的——这意味着无论我们添加同一节点多少次,它只会被添加一次。

实现共识协议算法的过程

如前所述,当两个节点的链不一致时,即发生了冲突。为解决这个问题,我们将规定 最长的有效链具有权威。换句话说,网络中最长的链就是 事实上的 标准链。“主链”可能会引起误解,而“标准链”更符合技术语境。通过这种方法,我们网络中的节点可以达成共识。

第一个方法 valid_chain() 负责检查链是否有效,通过遍历每个区块并验证哈希和工作量证明。

resolve_conflicts() 是一个方法,它会遍历所有邻近的节点,下载 它们的链,并使用上述方法验证。如果找到一个有效链,其长度大于我们当前的链,我们就用它替换我们现有的链。

让我们将这两个端点注册到我们的API,一个用于添加相邻节点,另外一个用于解决冲突问题:

此时,如果你想的话,可以换另一台机器,或者在同一台机器上使用不同的端口启动不同的进程。我在自己的机器上又启动了一个节点,并将其注册到我当前的节点上,使用的是不同的端口。因此,我现在有两个节点:<http://localhost:5000>http://localhost:5001

注册新的节点

然后我在节点2挖掘了一些新的区块,以确保链比其他节点更长。之后,我在节点1上调用GET /nodes/resolve,在那里链由共识算法重新调整。

共识算法的工作原理

就这样,搞定... 找些朋友一起帮忙测试一下你的区块链,试试看。

我希望这能激励你去创作新的东西。我对加密货币感到非常激动,因为我相信区块链将很快改变我们对经济、政府和记录保存的看法和方式。

更新: 我打算写一篇第二部分,让我们的区块链增加一个交易验证机制,并聊聊如何把区块链实际应用起来。

如果你喜欢这篇指南,或者有任何建议或问题,可以在评论中告诉我。如果你发现任何错误,欢迎在这里面的GitHub仓库https://github.com/dvf/blockchain 提交代码更正。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消