如何用Go开发一个区块链项目:ABTC


作者简介

强 科 臻

ABitchain 项目CTO,先后工作在互联网金融,区块链领域。专注于后端技术研发工作,主要专注 Java/Go,尤其是在分布式微服务,高并发,消息通信,区块链共识机制,加密技术等有丰富经验。







1.区块链简单介绍

2.如何开发区块链

3.区块链遇见Go

4.Q&A



1.区块链简单介绍


1.1   区块链特征

  • 去中心化

  • 可信任的机器,防篡改分布式数据库

  • 通过密码学构建账户体系

  • 共识,P2P 通信是交易基础 

  去中心化可以理解为在区块链网络中所有的网络节点都是对等的,没有任何对权,每个节点上做的都是一样的。区块链也可以简单的理解为去中心化的信任机器,这也是区块链最核心的价值。区块链通过密码学管理账户通过 P2P 网络,共识算法建立交易的基础在不借助第三方情况下,两个陌生人完成一笔交易。


1.2  区块链数据形态



   区块链通过不可逆的链式结构从创世块发起,以数据块的形式连接在一起,每个区块包含交易和验证信息,创世块包含初始的挖矿数据和规则


2.如何开发区块链


区块链开发模式有以下内容:

  • 共识模式

  • 账号地址生成算法

  • P2P 是怎么实现通信的

  • 智能合约

  • 智能 Pending 区规则简单介绍

  • 区块数据底层存储

共识模式

常见的共识算法有 POW(Proof of Work),POS(Proof of Stake),DPOS(Delegated Proof-of-Stake),BPFT(Practical Byzantine Fault Tolerance)。


共识机制: DPOS+BFT

  共识机制主要功能:定时任务管理,洗牌算法、代理池维护和投票机制。

1.定时任务管理。区块链的定时任务都是都是基于 NTP 来做的,通过 NTP 的协议,在相同的时间做相同的事,可以最大程度的保证时间的统一。主要设置的定时任务有定时洗牌、代理出块和节点数据同步。

2.洗牌算法。例如现在我们代理节点有 101 个,在某一个固定的时刻,通过洗牌的方式,将 101 个代理重新排队,将得到一个新的数据,这样设计的目的是在固定的周期内,洗牌的结果各个节点保持一致,整个区块链网络中让每一个节点洗牌结果一致,这是非常复杂的实现过程

3.代理池和投票机制普通用户账户上有一定的 Token 或达到某种条件,用户可以通过注册的方式成为代理候选人,注册为代理候选人就可以进入代理池空间。其他用户可以通过投票的方式支持候选人。投票得到确认,代理池就会实时选出获得投票最多的代理候选人进行排序,这时我们再回到上面的洗牌算法,得出一个新的序列,每个代理就会在新的时间开始出块了。


账户地址生成算法

   区块链作为一个交易性质的系统,账户是必不可少的区块链主要解决两方面的问题,第一是证明数字资产所有权问题,第二是验证交易合法性。



 通过密码学的应用,区块链证明数字资产所有权的问题图所示私钥通过一种非对称加密方式,椭圆加密算法推导出公钥,公钥推算出地址,这个顺序是不可逆的,所以说一旦拥有了私钥,就拥有了这个地址上所有的资产。解决了数字资产所有权的问题接下来看一下在交易当中如何证明一笔交易的合法性。如图所示,用户发起一笔交易,需要使用私钥,对交易数据签名,然后把签名交易数据在网络中传播, 其他节点收到交易后,需要使用用户的公钥,解密签名数据,如果能正常解密,并且验证通过,就能证明这笔交易的合法性,这一点是非对称加密算法所保证的。实际上私钥生成公钥的算法非常复杂,这幅图中只是画出了简单的推导过程。


  上图是 Achain 的地址生成过程一开始只产生一个随机数,经过一个多次哈希计算和 base58 的计算推倒出私钥,接下来通过椭圆曲线加密算法推导出公钥,公钥通过特定的方式推导出地址。


P2P实现通信



   要了解 P2P 通信,我们首先要了解一下 KAD 路由表,简单的说,这是一种分布式哈希表技术。每个节点内部都维护了这张路由表,如上图所示,可以把这张表简单理解为这个路由表,一行表示一个 K 桶,每个节点启动的时候会生成一个固定的节点编号,就是 NodelID。每个 K 桶的划分方式,是两个节点编号的距离范围值,图中第二列显示出了每个 K 桶容纳邻居节点,具体的距离范围,这个距离的计算方式是两个节点编号的二进制求异或值。例如:两个节点编号距离:0000000011 是 3 映射到 K2 桶中,简单理解了这张路由表,接下来了解一下本地节点是怎么维护这个表的,本地节点启动的时候会加载公共节点到对应的 K 桶中,接下来会随机的生成目标节点编号,计算本地节点和目标节点距离,然后从 K 桶中寻找距离最近的邻居节点,发送寻找命令,邻居节点收到寻找请求,会按照相同的方式找到离目标节点更近的节点,返回给本地节点,本地节点收到后,通过计算距离,放入对应的 K 桶中。这样循环处理,直到整个路由表填满邻居节点。现在,只要发起一笔交易,只需要广播到路由表中的邻居节点,就会迅速同步到全网络。



智能合约

   智能合约在区块链当中很重要。智能合约基于区块链,使用图灵完备的编程语言(例如: Solidity,lua 等)定义一段可运⾏的代码,这段代码完成了一系列的功能和约定接下来看一下智能合约怎么进入区块链执行的代码是存储在区块链的块上的。而且它一旦发布的话就无法修改了,会形成契约,我们可以调用智能合约里面定义的方法,按照我们约定方式执行,得到预想的结果。



   既然智能合约是一段代码,在区块链上普通的转帐一步就完成了,手续费一般情况下是固定的大家都很关心问题智能合约怎么计算手续费需要考虑到保护整个系统的问题,假如说写一段死循环,区块链可能会挂掉其实不是这样的,因为智能合约执行的时候,手续费是动态计算的,通过具体执行的代码一行一行计算手续费。是智能合约执行中手续费计算的一个参考列表你写了死循环会把账户余额全部扣完之后,执行就退出所以这个智能合约在区块链上是安全前提只要你有足够的手续费。


智能 Pending 区规则简单介绍

   简单说,Pending 区是一个缓冲区域,但是经常会被大家忽略,我认为它在区块链当中作用非常大。用户所有发起的交易,首先会被收集到 Pending 区,同时也起到了保护整个区块链网不被恶意攻击。所以在设计 Pending 区的时候,我们要考虑到保证每个用户都能有公平参与交易的权利,还要从宏观上控制,微观上调整交易行为,通过完备的经济模式,和多维度智能识别,让区块链处于一个健康的状态。



区块数据底层存储

  区块链存储数据结构要满足快速验证交易、有效防篡改、快速检索数据和分叉后能快速回滚等要求。



   因为实际存储很复杂,所以我们通过一个例子简单的了解一下。我们最熟悉的比特币底层使用最多的是默克尔树,以太坊使用的是 MPT 树,接下来,我们就从这种树结构开始了解,我们发起一笔交易,交易 hash 值当作 key,key 通过前缀匹配的方式存入下图树状数据结构中 A 位置,产生一个新的叶子结点,由于新节点插入,受影响的父级相关节点 key 值,从下到上,都要重新计算得到新的 Key 值,一直到树根。得到新 Root 节点,代理出块的时候,就会将这个新 Root 节点放入新的区块头中,这笔交易也会放入区块中。如图所示,旧的 root 在区块编号100的区块头中,新的 root 在区块101的区块头中,两个区块又是通过 hash 值连接在一起,所以任何节点出现修改,都会导致 Root 节点变化,Root 节点变化就会导致区块头 hash 值变化,这有效的防止数据的篡改。现在我们基本清楚了一笔新交易,是怎么进入区块中的。当然,这只是对区块链存储一个粗略的了解,实际的存储还要复杂的多。


到此,区块链产生地址,怎么发起交易,怎么验证交易,如何传播交易,如何在去中心的情况下达成共识,确认交易,交易如何存储有了一个简单认识。


3. Go 和区块链的结合


区块链项目使用的编程语言需要满足执行效率高,高并发,跨平台,高效的网络处理能力等要求,所以早期的区块链项目是以 C++ 为主。但是 C++ 入门起来可能也比较难,很多程序员也不是 C++ 出身,进入区块链再学 C++ 就有点难度了。

   Go 语言的出现某种程度上就填补了C++ 的短板

Go 语言有以下特点:

  • 编译速度快,部署简单,跨平台

  • 高性能,语言底层支持高并发

  • 和C的良好交互性

  • 良好的语言设计,更重要的是自带完善的工具链,大大提高了团队协作的一致性

  • 自动垃圾回收,省去了不少麻烦

  • 特殊的 channel 机制,解决系统内部频繁的通信

   我们是做区块链的团队,想把更多的精力投入在区块链的技术创新和研发上。我们可以用 Go 语言做区块链的创新,同时区块链也是风口的产业,区块链也可以推动 Go 语言的高速发展。所以我们的项目 ABTC 选用了 Go 语言开发,我们的同事都从 JAVA 转过来了,也很快上手了。

   我也做一个广告吧,其实我们整个 ABitchain 是一个技术至上的团队,我们整个团队主要是以社区的形式组织的,大家可以参与到我们的区块链研发中我们主要是以技术创新为主,我们的目标是区块链 3.0,我们下一个阶段会通过打造立体网络,构建多链并行的区块链,其中有很多技术创新点,大家有兴趣参与进来。


   欢迎大家加入我们,我的演讲就是这些内容,谢谢大家!

   

Q&A


   提问:我有一个比较小白的问题,之前看到讲智能合约那块,假设我有这样一个合约,我跟我朋友对赌,如果皇马赢了巴萨,我就给他一个币,这个合约怎么校验呢?

   强科臻:通过智能合约先把对赌的规则写好,参与对赌的两个人会预先把钱充入合约账户中, 比赛结果需要一段时间才出来,这正好和区块链高度是对应的,因为区块链高度随着时间推移是递增的,在某个确定的高度,调用智能合中提前写好的方法这个方法可以访问合约外比较有权威发布平台,获比赛果,根据结果,智能合约会自动钱打到对的账户上


  提问:假设我选的是 CCTV5 的官网查这个结果,我的朋友在 CCTV5 有人,他为了黑我这个币,把这个结果改了。

   强科臻:我想你说的这个可能性太小了,因为作为一个公众性的网站,公布的结果应该是有一定的法律效应的,而且你们既然是朋友,肯定是共识过的,认可 CCTV5 的官网的发布结果


   提问:我们两个认识,就是在这种条件下,我觉得可以说我们两个没有大的利益冲突,但是如果我们不是认识的,只是单纯的生意上的来往呢,如果我的合约变成了几百个币,他的利益很庞大了,他作假的成本可以通过合约回收回来。

   强科臻:这种几乎是不可能的,你们两个对赌的时候,在公认的结果出来之前,智能合约会保管对赌双方的资金安全。从外界获取公认的结果,这需要第三方支持,区块链只是帮你完成,把你们两个的币锁在这个合约里面不会跑,不会出现耍赖情况

   

   提问:你这个写到的是区块链的 3.0,你们的目标是什么时候达到 EOS 6 月份的进度呢?

   强科臻:我们马上上线的主网是区块链 2.5我们接下来已经规划了两个阶段,这两个阶段我计划年底就达到百万级别 TPS,区块链 3.0 是解决企业应用和数据过大的问题,接下来两个版本会重点解决这两个问题,通过立体网络和并链并行的方式解决。

   

   提问:我接着第一个问题问一下,如果说一场足球比赛放到合约里面,结果到某一个时间点,通过调用外部系统的数据获取结果,这一点我有一点疑惑,在智能合约里面如何会访问外部系统的数据?为什么问这个问题,从原理上来讲,以以太坊智能合约为例,单机的节点要全网所有的节点上,发布到节点上之后,每一个节点都验证这个结果,如果这个数据从外部系统获取过来的,有可能得到的数据结果就不一样,执行的结果就不一样,这个是怎么解决的?

   强科臻:因为智能合约在执行的时候,不管是在出块节点执行,还是普通节点执行,都是要保持结果一致的,你刚才说的也会产生这种情况,同步不下来这个块,但是对这个块是认可的,你收到这个块解析不了,但是通过程序是认可这个块。

  

   提问:我问一个问题,刚才一个同学问到 EOS 上线的问题,我想问的是 EOS 的融资额是非常大的,我想问一下 Achain 和 EOS 比都是同属于区块链3.0,Achain 和 EOS 有什么不同?

   强科臻:我们 Achain 是通过社区做开发的,整个团队都是比较年轻的,技术迭代非常快,技术实现上,EOS 是比特的团队,整体还是比特谷的基础上开发,我们 Achain,包括 ABitchain 都是通过全新的技术模板开发的,我觉得不管是开发力量上来说,我们还是优于 EOS,只是他出现的比较早,成名的比较早,所以是值比较大,但是我们也一定会努力的。技术上 EOS 是在比特的基础上开发,他们底层是用了东西,我们就不会用这些了,我们技术体系上通过打造立体网络,在立体网络上建造多链并发的形式去弥补单机的 TBS 不足的问题,后期我们可能会通过用集群自主的方式,也是于 IPFS 的形式去解决这种节点数据过多的问题,我们走的是两种技术路线。

   

   提问:我问一个问题,不太了解区块链,但是我听之前讲,也没有听明白区块链到底能用来干什么,按照我的理解,其实区块链也是一个数据库,我能这么理解吗,如果是中心化的话,我只要一个人有写的权限,所有人都有读的权限,这个和区块链有什么区别吗?

   强科臻:这个理解非常好,首先区块链可以简单的用数据库实现,但是面临一些问题,区块链所说的分布式数据库不是这儿存一点,那儿存一点,而是某一个节点都存有所有的数据,你一个人往里面写,如果你挂了,整个链就停了,而且你写入没有经过共识,大家怎么信任你呢,要知道区块链出现解决的就是信任问题。

   提问:为什么非得去中心化呢?

   强科臻:整个社会的核心问题就是信任问题,区块链的出现就是解决信任问题,提供了通过机器承担信任的中介,解决第三方信用的问题,整个网络中你不需要信任任何人,只要把交易推出去就会成交。

   

   提问:你刚才说到百万 TPS 通过哪些方式实现,现在所有的区块链 TPS 距百万都是差得非常远的。

   强科臻:其实区块链是单机应用,通过各种性能优化,把单机应用的性能压缩到极致的时候,TPS 也过不了万,这是肯定的,只有进行横向扩展,通过多链并行方式解决这个问题。

   提问:横向就有分叉的问题吗?

   强科臻:任何时候都有可能存在分叉问题,因为网络是不稳定的,我们会通过立体网络和共识机制去解决这个问题,我们在共识机制选择上选择 DPOS 加BFT 的话,其实是不错的选择,这样可以最大程度的降低分叉的可能性,而且后期因为BFT是拜占庭的算法,但是其实把这个算法进行优化、升级,可以最大程度上降低分叉,有可能就是不分叉。

   

   提问:刚才您说到到数据量太多之后有轻节点出现,数据量跑了几年之后,有了10T、100T 的时候,那之后所谓的去中心化又回到了中心化是吧?

   强科臻:我觉得不会的,因为我说的这个集群自组的方式是一个奖励模式也是挖矿模式,大家组装在一起,每个地方存一块数据,大家会把整个数据集中起来,但是这样的集中不是一个,会有很多个,这样有一种奖励机制,你只要帮别人验证了,就能拿到奖励,这个奖励机制会促使大家做这件事情,未来就有人通过轻节点迅速达成交易,有些人就愿意提供这种验证方式,去服务大家,最后不会是只有一个节点存储很多数据。

   提问:但是也可能只有几个核心节点,这时候也会出现篡改的情况。

   强科臻:核心节点不会是一个,有可能是一个群体网络,去中心化是一个相对的,是最大程度的去中心化。


2018年的 Gopher Meetup 将在深圳开启巡回第一站,这一次邀请了很多新的讲师给大家一起交流分享Go的使用经验〜

点击阅读原文报名参加

展开阅读全文

没有更多推荐了,返回首页