最新的区块链养殖app:使用Go语言编写区块链P2P网络

  

  什么是P2P网络

  在真正的P2P架构中,不需要中心化的服务来维护区块链的状态。例如,当你给朋友发送比特币时,比特币区块链的“状态”应该更新,这样你朋友的余额就会增加,你的余额就会减少。

  在这个网络中,不存在一个权力高度中心化的机构来维护状态(银行就是这样的中心化机构)。对于比特币网络来说,每个节点都会维护一份完整的区块链状态,当交易发生时,每个节点的区块链状态都会得到更新。这样,只要网络中51%的节点对区块链的状态达成一致,那么区块链网络就是安全可靠的,具体可以阅读这篇一致性协议文章[4]。

  本文将继续之前的工作,200行Go代码实现区块链[5],并加入P2P网络架构。在继续之前,强烈建议你先阅读该篇文章,它会帮助你理解接下来的代码。

  开始实现

  编写P2P网络可不是开开玩笑就能简单实现的,有很多边边角角的情况都要覆盖到,而且需要你拥有很多工程学的知识,这样的P2P网络才是可扩展、高可靠的。有句谚语说得好:站在巨人肩膀上做事,那么我们先看看巨人们提供了哪些工具吧。

  喔,看看,我们发现了什么!一个用Go语言实现的P2P库go-libp2p[1]!如果你对新技术足够敏锐,就会发现这个库的作者和IPFS的作者是同一个团队。如果你还没看过我们的IPFS教程[2],可以看看这里,你可以选择跳过IPFS教程,因为对于本文这不是必须的。

  警告

  目前来说,go-libp2p主要有两个缺点:

  1、安装设置比较痛苦,它使用gx作为包管理工具,怎么说呢,不咋好用,但是凑活用吧

  2、目前项目还没有成熟,正在紧密锣鼓的开发中,当使用这个库时,可能会遇到一些数据竞争(datarace)

  对于第一点,不必担心,有我们呢。第二点是比较大的问题,但是不会影响我们的代码。假如你在使用过程中发现了数据竞争问题,记得给项目提一个issue,帮助它更好的成长!

  总之,目前开源世界中,现代化的P2P库是非常非常少的,因为我们要多给go-libp2p一些耐心和包容,而且就目前来说,它已经能很好的满足我们的目标了。

  安装设置

  最好的环境设置方式是直接clonelibp2p库,然后在这个库的代码中直接开发。你也可以在自己的库中,调用这个库开发,但是这样就需要用到gx了。这里我们使用简单的方式,假设你已经安装了Go:

  goget-dgithub.com/libp2p/go-libp2p/…

  cdgo-libp2p

  make

  makedeps

  这里会通过gx包管理工具下载所有需要的包和依赖,再次申明,我们不喜欢gx,因为它打破了Go语言的很多惯例,但是为了这个很棒的库,认怂吧。

  这里,我们在examples子目录下进行开发,因此在go-libp2p的examples下创建一个你自己的目录

  mkdirhttps://www.qukuaiwang.com.cn/news/examples/p2p

  然后进入到p2p文件夹下,创建main.go文件,后面所有的代码都会在该文件中。

  你的目录结构是这样的:

  

  好了,勇士们,拔出你们的剑,哦不,拔出你们的main.go,开始我们的征途吧!

  导入相关库

  这里申明我们需要用的库,大部分库是来自于go-libp2p本身的,在教程中,你会学到怎么去使用它们。

  

  spew包可以很方便、优美的打印出我们的区块链,因此记得安装它:

  gogetgithub.com/davecgh/go-spew/spew

  区块链结构

  记住,请先阅读200行Go代码实现区块链,这样,下面的部分就会简单很多。

  先来申明全局变量:

  

  我们是一家健康看护公司,因此Block中存着的是用户的脉搏速率BPM

  Blockchain是我们的"状态",或者严格的说:最新的Blockchain,它其实就是Block的切片(slice)

  mutex是为了防止资源竞争出现

  下面是Blockchain相关的特定函数:

  

  isBlockValid检查Block的hash是否合法

  calculateHash使用sha256来对原始数据做hash

  generateBlock创建一个新的Block区块,然后添加到区块链Blockchain上,同时会包含所需的事务

  P2P结构

  下面我们快接近核心部分了,首先我们要写出创建主机的逻辑。当一个节点运行我们的程序时,它可以作为一个主机,被其它节点连接。下面一起看看代码:

  

  

  makeBasicHost函数有3个参数,同时返回一个host结构体

  listenPort是主机监听的端口,其它节点会连接该端口

  secio表明是否开启数据流的安全选项,最好开启,因此它代表了"安全输入/输出"

  randSeed是一个可选的命令行标识,可以允许我们提供一个随机数种子来为我们的主机生成随机的地址。这里我们不会使用

  函数的第一个if语句针对随机种子生成随机key,接着我们生成公钥和私钥,这样能保证主机是安全的。opts部分开始构建网络地址部分,这样其它节点就可以连接进来。

  !secio部分可以绕过加密,但是我们准备使用加密,因此这段代码不会被触发。

  接着,创建了主机地址,这样其他节点就可以连接进来。log.Printf可以用来在控制台打印出其它节点的连接信息。最后我们返回生成的主机地址给调用方函数。

  流处理

  之前的主机需要能处理进入的数据流。当另外一个节点连接到主机时,它会想要提出一个新的区块链,来覆盖主机上的区块链,因此我们需要逻辑来判定是否要接受新的区块链。

  同时,当我们往本地的区块链添加区块后,也要把相关信息广播给其它节点,这里也需要实现相关逻辑。

  先来创建流处理的基本框架吧:

  

  这里创建一个新的ReadWriter,为了能支持数据读取和写入,同时我们启动了一个单独的Go协程来处理相关读写逻辑。

  读取数据

  首先创建readData函数:

  

  该函数是一个无限循环,因为它需要永不停歇的去读取外面进来的数据。首先,我们使用ReadString解析从其它节点发送过来的新的区块链(JSON字符串)。

  然后检查进来的区块链的长度是否比我们本地的要长,如果进来的链更长,那么我们就接受新的链为最新的网络状态(最新的区块链)。

  同时,把最新的区块链在控制台使用一种特殊的颜色打印出来,这样我们就知道有新链接受了。

  如果在我们主机的本地添加了新的区块到区块链上,那就需要把本地最新的区块链广播给其它相连的节点知道,这样这些节点机会接受并更新到我们的区块链版本。这里使用writeData函数:

  

  首先是一个单独协程中的函数,每5秒钟会将我们的最新的区块链状态广播给其它相连的节点。它们收到后,如果发现我们的区块链比它们的要短,就会直接把我们发送的区块链信息丢弃,继续使用它们的区块链,反之则使用我们的区块链。总之,无论哪种方法,所有的节点都会定期的同步本地的区块链到最新状态。

  这里我们需要一个方法来创建一个新的Block区块,包含之前提到过的脉搏速率(BPM)。为了简化实现,我们不会真的去通过物联网设备读取脉搏,而是直接在终端控制台上输入一个脉搏速率数字。

  首先要验证输入的BPM是一个整数类型,然后使用之前的generateBlock来生成区块,接着使用spew.Dump输入到终端控制台,最后我们使用rw.WriteString把最新的区块链广播给相连的其它节点。

  牛逼了我的哥,现在我们完成了区块链相关的函数以及大多数P2P相关的函数。在前面,我们创建了流处理,因此可以读取和写入最新的区块链状态;创建了状态同步函数,这样节点之间可以互相同步最新状态。

  剩下的就是实现我们的main函数了:

  

  

  

  首先是创建一个创世区块(如果你读了200行Go代码实现你的区块链,这里就不会陌生)。

  其次我们使用go-libp2p的SetAllLoggers日志函数来记录日志。

  接着,设置了所有的命令行标识:

  secio之前有提到,是用来加密数据流的。在我们的程序中,一定要打开该标识

  target指明当前节点要连接到的主机地址

  listenF是当前节点的监听主机地址,这样其它节点就可以连接进来,记住,每个节点都有两个身份:主机和客户端,毕竟P2P不是白叫的

  seed是随机数种子,用来创建主机地址时使用

  然后,使用makeBasicHost函数来创建一个新的主机地址,如果我们只想做主机不想做客户端(连接其它的主机),就使用if*target==“”。

  接下来的几行,会从target解析出我们要连接到的主机地址。然后把peerID和主机目标地址targetAddr添加到"store"中,这样就可以持续跟踪我们跟其它主机的连接信息,这里使用的是ha.Peerstore().AddAddr函数。

  接着我们使用ha.NewStream连接到想要连接的节点上,同时为了能接收和发送最新的区块链信息,创建了ReadWriter,同时使用一个Go协程来进行readData和writeData。

  哇哦

  终于完成了,写文章远比写代码累!我知道之前的内容有点难,但是相比P2P的复杂性来说,你能通过一个库来完成P2P网络,已经很牛逼了,所以继续加油!

  完整代码

  mycoralhealth/blockchain-tutorial

  运行结果

  现在让我们来试验一下,首先打开3个独立的终端窗口做为独立节点。

  开始之前,请再次进入go-libp2p的根目录运行一下makedeps,确保所有依赖都正常安装。

  回到你的工作目录examples/p2p,打开第一个终端窗口,输入

  gorunmain.go-l10000-secio

  

  细心的读者会发现有一段话"Nowrun…",那还等啥,继续跟着做吧,打开第二个终端窗口运行:

  gorunmain.go-l10001-d-secio

  

  这是你会发现第一个终端窗口检测到了新连接!

  

  接着打开第三个终端窗口,运行:

  gorunmain.go-l10002-d-secio

  

  检查第二终端,又发现了新连接

  

  接着,该我们输入BPM数据了,在第一个终端窗口中输入"70",等几秒中,观察各个窗口的打印输出。

  

  来看看发生了什么:

  终端1向本地的区块链添加了一个新的区块Block

  终端1向终端2广播该信息

  终端2将新的区块链跟本地的对比,发现终端1的更长,因此使用新的区块链替代了本地的区块链,然后将新的区块链广播给终端3

  同上,终端3也进行更新

  所有的3个终端节点都把区块链更新到了最新版本,同时没有使用任何外部的中心化服务,这就是P2P网络的力量!

  我们再往终端2的区块链中添加一个区块试试看,在终端2中输入"80"

  

  

  结果忠诚的记录了我们的正确性,再一次欢呼吧!

  下一步

  先享受一下自己的工作,你刚用了区区几百行代码就实现了一个全功能的P2P网络!这不是开玩笑,P2P编程是非常复杂的,为什么之前没有相关的教程,就是因为太难了。

  但是,这里也有几个可以改进的地方,你可以挑战一下自己:

  之前提到过,go-libp2p是存在数据竞争的Bug的,因此如果你要在生产环境使用,需要格外小心。一旦发现Bug,请反馈给作者团队知道

  尝试将本文的P2P网络跟之前的共识协议结合,例如之前的文章PoW和PoS

  添加持久化存储。截止目前,为了简化实现,我们没有实现持久化存储,因此节点关闭,数据就丢失了

  本文的代码没有在大量节点的环境下测试过,试着写一个脚本运行大量节点,看看性能会怎么变化。如果发现Bug记得提交给我们[6]

  学习一下节点发现技术。新节点是怎么发现已经存在的节点的?这篇文章是一个很好的起点[3]

  声明:本文由入驻区块网专栏作者撰写,观点仅代表作者本人,绝不代表区块网赞同其观点或证实其描述。

  更多名家专栏精品文章:http://www.qukuaiwang.com.cn/zhuanlan.html

文章内容系本站作者个人观点,不代表本站对其观点赞同或支持,文章的版权归该作者所有。如需转载,请注明文章来源。本文地址:http://www.cis.net.cn/kejikuaixun/43221.html
留言与评论(共有 条评论)
验证码:

最新文章

使用Go语言编写区块链P2P网络

科技快讯
什么是P2P网络在真正的P2P架构中,不需要中心化的服务来维护区块链的状态。例如,当你给朋友发送比特币时,比特币区块链的“状态”应该更新,这样你朋友的余额就会增加,你的余额就会减少。在这个网络中,不存在一个权力高度中心化的机构来维护状态(银行就是这样的中心化

区块链趣评:币安何一,公关能力实在强!

科技快讯
一分钟吐槽:有大V放话——凡是有超级节点的币,都TMD超级垃圾!你们觉得呢?1、币安何一:对于红杉的事情是大家过度解读了币安联合创始人何一在今日直播中表示,币安当时比较弱小,的确需要大的投资基金帮助,但后来发现红杉对币安未来的发展帮助比较有限。中国传统文化喜欢给对方面子,不想币安这样怼来怼去。公司能否发展好不是看和谁的关

?链客猩球 新手攻略

科技快讯
链客猩球是一款区块链游戏,在游戏中让您的凯撒成长、繁衍、征战,为您获得源源不断的收益,快来体验专属您的猩球如何崛起吧!崛起第一步:注册账号在注册游戏后,需要绑定自己的链克口袋地址。根据您输入的链克口袋地址确定后,系统会随机给您一个链克数值,需要您使用已绑定的链克钱包进行向系统提示的链克口袋地址转入指定

比原项目周报(2018.8.27更新)

科技快讯
开发进展Core:后端增加版本提示更新接口,包括当前版本、是否存在更新、是否存在重要更新、最新版本;「先知计划」完善api文档、重新调整数据类型&结构;改造equity编译器支持资产值的计算;调研equity编译器变量赋值的问题;SPV:添加SPV默克尔树证明算法以及对应的测试用例;添加FilterAddMessage用于添加轻节点过滤地址,并限制地址的大小

美国特拉华州成区块链热土,承认多项区块链应用合法

科技快讯
美国特拉华州州长正式将一项法案写入法律,承认区块链股票交易的合法性。今年4月,特拉华州律师协会(DSBA)公司法部门同意了对特拉华州法律的修改,允许该州内企业用区块链登记公司记录,并赋予相应的法定权利。6月底,这一法案在众议院以40票同意1票反对的结果正式获批。特拉华州这场区块链运动始于2016年5月,当时的州长JackMarkell公布

链吧财经协办“首届火币中环数字财富高峰论坛”于5月19日在香港召开

科技快讯
2018年5月19日,火币Pro与中环数字财富联合主办的“火币中环数字财富高峰论坛暨中环数字学院数字货币交易高管培训”,将在香港四季酒店隆重举行。此次会议将是2018年对冲基金业最重要的一场会议,全球最大的数字货币交易所之一火币PRO,派出最豪华管理层莅临香

YOYOW主网发布一周年回顾,继续通往未来

科技快讯
YOYOW的诞生及其理念近年来,随着互联网科技企业逐步规模成型和地位稳固,无论是资本还是整个经济环境都在寻找新的成长点,期待这个新的成长点能够具有革命性。而最受到关注的前沿技术无疑是区块链技术了。区块链技术的去中心化、透明、注重安全和隐私的特点,使得它在诸多场景上的运用都会带来行业的

MenaPay完全基于区块链的支付平台

科技快讯
MenaPay是首个完全基于区块链的支付平台,主要为中东和北非地区(MENA)提供支持。它允许用户通过区块链来实行比任何传统支付网关更快,更安全及更低收费的交易,并确保他们免受加密货币波动的影响。MenaPay被设计为并旨在符合伊斯兰金融法规。得感谢区块

Axie Infinity:幻想生物的天堂

科技快讯
随着链游的种类不断增多,一如2018年火爆的AxieInfinity链游被“冷落”在所难免,虽然AxieInfinity上线一年多,但是游戏的玩法和观感设计依然能满足今天很多不同段位的“氪金”玩家。游戏介绍AxieInfinity是一款基于以太坊开发的、收集和饲养幻想生物的链游。所谓幻想生物,就是你永远不会想到鱼的头上长着鹿角,或是背上插着刀·

霍金他只是去了他最爱的宇宙

科技快讯
1月8日,是霍金的诞辰,也是伽利略的忌日。3月14日,是爱因斯坦的诞辰,也是霍金的忌日。与两个伟人奇妙的交集,也让他成为了伟人。英国当地时间2018年3月14日凌晨3时46分,斯蒂芬·威廉·霍金去世,享年76岁。他生于英国牛津,童年时喜欢设计极为复杂的玩具。他于21岁患病,医生曾诊断他只能活两年,可他一直坚强地活了下来。他23岁取得博士