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

mob604756f0bbf4 · · 2412 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

作者简介

强 科 臻

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

目录

1.区块链简单介绍

2.如何开发区块链

3.区块链遇见Go

4.Q&A

1.区块链简单介绍

1.1 区块链特征

  • 去中心化

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

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

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

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

1.2 区块链数据形态

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

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

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 或达到某种条件,用户可以通过注册的方式成为代理候选人,注册为代理候选人就可以进入代理池空间。其他用户可以通过投票的方式支持候选人。等投票得到确认,代理池就会实时选出获得投票最多的代理候选人进行排序,这时我们再回到上面的洗牌算法,得出一个新的序列,每个代理就会在新的时间开始出块了。

账户地址生成算法

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

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

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

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

P2P实现通信

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

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

智能合约

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

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

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

智能 Pending 区规则简单介绍

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

区块数据底层存储

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

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

因为实际存储很复杂,所以我们通过一个例子简单的了解一下。我们最熟悉的比特币底层使用最多的是默克尔树,以太坊使用的是 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 的时候,那之后所谓的去中心化又回到了中心化是吧?

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

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

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


有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:mob604756f0bbf4

查看原文:如何用Go开发一个区块链项目:ABTC

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2412 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传