第一次接触铂链是在初链群中被铂链群管拉进技术群时开始的。铂链对我来说印象最深的还是他那长达70多页的白皮书。作为一条主攻AI领域的专用公链,我在还没开始看铂链项目代码时就设想铂链对于AI部分的处理应该是在区块链内部构建一个运行AI运算的基础设施模块,再由区块链完成AI模块产出数据的确权,AI的运算可能将一部分交由智能合约处理,做到运算和数据双双上链。AI计算天生是构建在大数据之上的,可以将大数据比作粮食,AI比作野兽,野兽只有在充分进食后才能进化,所以如果AI运算的基础设施和区块链整合在一起那区块链一定会大数据紧密结合,区块链如果和大数据紧密结合那对于数据存储这一块儿的要求就非常高了,数据分片技术可能会成为一个瓶颈。AI+大数据+区块链?再加上那70多页的白皮书?基于以上猜想,我对铂链充满好奇。在进入铂链技术群之后,我就从GitHub上下载了铂链的代码,花了一个星期左右的时间看完了绝大部分代码,也发现了一些小BUG和不足,目前的感受是铂链的代码其实写得挺好的,看得出来是在一个经验丰富的架构师的带领下发起的项目,但在架构设计上和我之前对铂链的设想有明显的出入,我并未看到任何和AI相关的代码,也未发现对于数据储存这一块儿有明显亮眼的处理。
在铂链技术群里发表了自己对铂链架构设计的看法,也得到了铂链开发者的回应,这才认识到自己对“AI+区块链”的认知存在偏差。“AI+区块链”其实并不是将AI和区块链整合在一起,AI构建在大数据之上,而区块链则是作为AI在数据确权和分享上的一种延申。根据 《Blockchain —构建新一代的人工智能生态系统(http://www.blockchainbrother.com/article/1024)》 这篇文章的描述,AI的发展归咎于算力、算法和数据这三个核心因素。AI算法在上世纪就已被研究透彻,但当时AI并未发展起来的原因正是算力和数据的缺失。在21世纪的今天,CPU/GPU的算力依据摩尔定律(甚至超过摩尔定律)在增长,互联网的发展加快了社会进步的节奏,以往在线下堆积的数据也逐渐搬到了线上,大数据和云计算的出现更是让AI在算力和数据上的不足得以弥补,所以近几年AI领域出现了爆发式地增长:算法一直都有,现在算力和数据也跟上了,AI发展的三要素也都集齐了。虽然算力和数据跟上了,但也只是在“量”上粗暴地增加了而已,在算力共享、数据交换和数据确权等“质”的转变上,由于区块链的出现也迎来了转机。区块链构建在密码学基础上的数字身份让数据天然的具有“身份”属性,其去中心化的特性也让数据的流转脱离了中心化的束缚而变得更加高效。数据具有身份验证而且流通更快,这让AI产生的数据更具价值,再配合上区块链网络庞大的协同计算能力,AI的运转速度无疑将更上一个台阶。所以我想,像铂链这样主打AI的区块链,更多的还是为现有的AI体系提供数据上链和分享服务,而并不是构建一个独立的AI生态系统,如果是这样,那以后跨链通信应该会是这些主攻AI市场的区块链所应该具备的功能。
铂链代码由Go语言编写,代码结构比较清晰,代码质量和原创程度都比较高,没有看到明显抄袭的痕迹。铂链主体采用高并发的Actor模型构建,由ProtoActor.Go实现。铂链将API服务(Api)、链处理(Chain)、P2P网络处理(Net)、区块生产(Producer)、交易处理(Transaction)和可选的MongoDB服务(OptionDB)抽象为对应的Actor模型:
- API服务:以RPC(远程过程调用)的形式对外提供API服务,与铂链的消息交互采用Protobuf编码,天然支持由多种语言编写的外部应用程序
- 链处理:实现铂链的区块链数据库功能,包括区块查询、交易查询、区块接收与广播和链信息查询功能
- P2P网络处理:实现交易和区块在P2P网络中的传播功能
- 区块生产:每500毫秒检测一次自己是否是当前区块的生产者,是的话就构建一个区块并发送给“链处理”处理
- 交易处理:从终端或P2P网络接收交易放入交易池,并将交易发送给“P2P网络处理”处理,支持获取所有可加入区块的交易和交易的移除操作
- MongoDB服务:MongoDB服务作为一个可选服务,可在配置文件中配置是否启用,启用MongoDB服务后可以将区块写入MongoDB中
每一个Actor对应一个线程,完全独立地运行,与外部隔离。Actor之间的交互手段采用消息通信地方式,只有通过发送消息才能改变一个Actor的内部状态。铂链使用Actor模型让几个可以独立运行的模块在高并发的环境下并发运行,在数据量大的环境中运行效率应该会有比较明显的提升。
几乎每一个区块链项目都提供了基于Http的Restful接口,提供Restful化的接口可以提供统一的接口调用规则,适合让区块链服务器同时服务多种类型的终端,其中一些终端就包括区块链浏览器和在线钱包。铂链的Restful服务提供查询区块、交易和账户的服务,也提供发送交易、获取合约ABI(应用程序二进制接口)和合约代码的服务,铂链的命令行客户端就使用Restful接口与区块链通信。
除开像MongoDB这样的分布式数据库外,铂链还使用了另外两个嵌入式数据库,分别是LevelDB和BuntDB。以太坊中也使用LevelDB为数据持久化提供服务,由于以太坊采用特殊的MPT字典树结构储存状态,所以每个树节点的值都可以键值对的形式储存在LevelDB中。铂链采用的区块储存结构非常简单,就是普通的二进制序列,所以对于区块和区块头的增删查改就交由像LevelDB这样的以键值对形式组织的非结构化数据库来做,非常方便。BuntDB是用Go语言编写的内存数据库,类似于Redis和Memcache,提供数据持久化和查询功能,支持结构化查询,铂链使用它完成账户的存储和结构化查询操作。由于铂链采用DPOS作为其共识算法,经常需要对投票账户进行排序,所以使用BuntDB这类的提供结构化查询服务的数据库是一个不错的选择,而且BuntDB是个内存数据库,所以也不需要再额外使用缓存保存频繁查找的数据,直接用就行:
- MongoDB数据库: 以可选插件形式存在的Actor模块,主要用于持久化保存链上的区块,还提供转账和创建账户两个内置的合约功能,和LevelDB功能重叠,但作为一个本身就提供数据分片存储功能的主从分布式数据库,可能在以后区块数据激增的情况下接替部分LevelDB的功能,为铂链提供一个数据分片的解决方案。
- LevelDB数据库:以键值对的形式为区块链提供区块存储和查找功能,以哈希作为键,以BPL(Bottos-Pack-Library,铂链自研二进制编解码库)编码作为值,但需要配合LruCache为其提供辅助的数据缓存服务
- BuntDB数据库:内存数据库高效存取,不需要提供数据缓存服务,并且还支持结构化查询和回滚操作,特别适合需要频繁存取和排序查找的账户数据的存储
不同于基于POW共识设计的区块链,基于DPOS共识设计的区块链由于可能存在固定的代理人节点,所以在区块链的对等网络中,对节点发现机制的复杂度要求就没那么高。很多基于POW共识算法设计的区块链在节点发现机制上采用DHT(分布式哈希表)系列算法,比如初链就采用Kadelima作为其节点发现机制的算法,按照距离让节点在对等网络中均匀排布,以最大化优化消息在网络中的传播效率,为了实现内网穿透,一般采用UDP协议建立连接,而铂链则自研了一套基本能用的节点发现算法,节点之间采用TCP协议连接。在铂链的节点发现算法中,存在三个层次的角色,分别是Neighbors、Candidates和Runners,在配置文件中预配置的种子节点列表则首先放入Neighbors层次中。节点在三个层次之间通过Discover模块驱动流转,其中Runners层次中的节点通过KeepAlive模块完成心跳检测。具体的发现机制如下:
- 角色介绍:
a) Neighbors层次:处在该层次的节点都是邻居,所有在Neighbors层次中的节点都没有与其建立连接,都以IP和端口等节点信息的形式存储,处在该层次的节点通过Discover模块与本节点建立连接后被提升至Candidates层次成为候选者节点
b) Candidates层次:处在该层次的节点都是候选者,本节点与所有候选者节点都已经建立了TCP连接,在连接建立后会立即开启三次握手流程,在双方都已达到最后一次握手流程时会互相将对方提升至Runners层次成为连接者
c) Runners层次:处在改层次的节点都是正式的连接者,所有的P2P通信都会通过他们进行转发,也会通过他们完成接收,可广播也可单播。- 流程介绍:
A) 从配置文件中读取所有种子节点的IP和端口等信息,全部放入Neighbors层次中
B) Discover模块每5秒从Neighbors层次中取出10个节点信息并尝试建立TCP连接,连接成功后将节点从Neighbors层次中移除并放入Candidates层次中
C) 每5秒中向所有处于Candidates层次中的节点开启三次握手流程并将对应节点的握手计数器加1,如果超过10次握手都没有成功那直接关闭和该节点的连接,然后将节点从Candidates层次中移除
D) 在三次握手流程结束后将节点从Candidates层次中移除并放入Runners层次中并初始化该节点的心跳计数
E) KeepAlive模块每10秒向所有处于Runners层次中的节点发送一次Ping、Pong心跳检测,在收到Pong消息后将对应节点的心跳计数加1
F) 在终端启动之后的前三个8秒中向所有处于Runners层次中的节点索要他们的Runners层次中的所有节点信息,将这些节点信息全部传回本节点,然后放入本节点的Neighbors层次中
G) 在终端启动之后的第三个8秒之后的每8秒向最新加入Runners层次中的节点所要他的Runners层次中的所有节点信息,将这些节点信息全部传回本节点,然后放入本节点的Neighbors层次中
H) KeepAlive模块每40秒检测一次在Runners层次中的节点的心跳状态,将所有心跳计数为0的节点从Runners层次中移除,关闭和他们的连接,然后放入Neighbors层次中
作为掺杂了“人治”因素的共识算法,DPOS共识算法也像POW共识算法那样饱受争议,POW共识算法在挖矿算法设计不当的情况下,容易催生ASIC专用矿机从而在人性“逐利”的驱使下导致算力逐步集中为矿池,导致去中心化程度明显降低。针对目前POW共识算法的不足,DPOS共识算法并没有给出一个优化方案,比如基于抗ASIC专用矿机挖矿算法的POW共识算法优化(比如初链就设计了一套抗ASIC专用矿机的挖矿算法),而是基于目前无法做到完全去中心化的事实,设计出一套从一开始就摒弃追求完全去中心化的初衷,以牺牲去中心化程度为代价来换取区块链性能提升的基于“人治”的共识算法。DPOS共识算法涉及代理人节点的竞选、投票和换届,获得投票数量排前几位的竞选者将在当前的代理人换届周期内被提升为正式的区块生产代理人节点,即记账节点。每一个代理人节点都会在换届周期内被分配一个出块时间槽,轮到你出块时就必须在当前时间槽内完成区块的生成和广播,不然就会被记录为错过一次出块任务,这个记录会广播给全网,其他节点在收到这些记录信息后自然也能权衡在下次代理人换届时是否还继续给你投票。每一个节点都可以参与代理人竞选,不过有没有节点给你投票那就不是你能决定的了,人都有惰性和从众心理,获票数量始终在前的代理人节点会在头部效应的影响下,地位越来越稳固,留给其他“小白节点”的机会就会越来越少,除非他们“资金”雄厚。DPOS共识算法会是在区块链去中心化程度和运行效率的折中权衡下的一个中长期共识方案,但一定不会是公链的最终共识形态。DPOS共识算法适合那种需要由人或社区去维护运行在区块链之上的产品的专用公链,这些产品质量维护的好坏程度很难用算法去衡量其背后的工作量,但使用这些产品的用户却能深切感受到,在这种环境下设计的区块链适合选用DPOS作为其共识算法,因为既然只能由人去确认区块链的运行状况,那“人治”就是不可避免的也是十分必要的一个环节,比如触控科技的BCX区块链游戏引擎项目就是一个很好的例子。BCX区块链采用DPOS共识算法,专为区块链游戏生态打造,如果人人都能参与区块链游戏的维护,都有权力为游戏添加更多好玩的元素,那游戏是否好玩就需要由玩家去鉴定,玩家会一直把票投给能让游戏真正变得好玩的维护者让他们变成代理人,这些代理人一旦作恶让游戏变得不好玩或者不平衡,玩家自然不会再把票投给他们。扯了那么多都没有讲铂链DPOS共识算法的运行过程,铂链团队设计的DPOS共识算法和传统的DPOS共识算法基本相同,没有太大的出入,最多就调整了下代理人的选取规则。不过目前铂链还处在测试阶段,共识流程为测试网络中的流程,在正式网络发布后应该会有完善和变更。测试网络中的共识流程如下:
a) 节点在区块链初始化时创建Bottos内置合约账户并注入大量资金,如果Bottos合约账户已存在则跳过此步骤
b) 通过向区块链发送合约交易调用内置合约代码,与共识相关的内置合约功能包括创建账户、交易转账、划拨权益、注册代理人竞选和代理人投票
c) 节点先发送“创建账户”的交易创建密钥账户、余额账户和权益账户,然后发送“交易转账”交易从Bottos内置账户中索取需要的转账金额填充余额账户,再发送“划拨权益”交易将资金从余额账户划拨至权益账户,最后发送“注册代理人竞选”交易创建代理人投票账户
d) 以上所有交易都会进行全网广播并执行对应的合约功能,这样全网所有节点都能看到任意一个节点创建的代理人投票账户,他们可以选择给指定的代理人投票账户投票,通过发送“代理人投票”交易将权益账户中的余额用来更新指定注册竞选代理人的投票状态
e) 每29个区块完成一次代理人换届,所有节点在收到区块编号是29的倍数的区块时开启代理人换届流程,从所有代理人投票账户中选取28个票数最高的账户和1个剩余完成时间最小的账户,将这29个账户随机打乱后就成为本届的出块代理人账户名单
f) 根据节点的系统时间获得当前的出块槽位(Slot),再根据出块槽位从29个代理人账户中选取对应槽位下的代理人账户,如果该账户在节点的本地账户名单中,那么在代理人参与率和出块调度时间都达标的情况下,本节点会被指定为当前时间段内的出块人,在立即将交易打包进区块并全网广播后完成本轮出块任务
g) 在目前的测试网络中,节点在出块后并没有分配相应的记账奖励,链上所有的资金都来自于初始化的Bottos内置合约账户中,该账户具有非常庞大的资金储备,足够在测试网络中使用,在正式网络中将完善整个奖励过程
同以太坊类似,铂链也具有普通账户和合约账户两种账户类型。在铂链中,普通账户和合约账户都使用同样一个数据结构,在普通账户的基础上为其部署智能合约代码和ABI数据(可选),那普通账户就算是一个合约账户了。铂链的智能合约模块主要为内置的合约账户服务,该内置合约账户名为“Bottos”,包含多种基础的合约方法,像创建账户、交易转账、部署智能合约代码和部署ABI数据等方法都实现在该合约里,“Bottos”内置合约也是唯一一个在铂链中使用ABI来为合约方法的调用参数进行解码的智能合约,因为在WASM虚拟机中并未看到有对合约参数进行解码的操作,这可能是因为目前铂链还处在测试阶段的原因,也可能是WASM虚拟机在运行合约方法时不需要从外部提供调用参数。在铂链里所有的交易都是在调用智能合约里的方法,像最基本的交易转账等功能也都是由内置合约方法实现。节点在执行一个交易时会先判断交易触发的合约方法是否为内置合约方法,如果是则解码交易中附带的调用参数,然后调用该内置合约方法,比如交易转账,如果不是那么就交给WASM虚拟机处理,WASM虚拟机会从交易指定的合约账户中查询部署的智能合约代码,在解析完合约代码后就会开始运行交易中指定的合约方法,如果方法执行完毕后还发现有子交易未处理,那么就继续递归地执行下去,但递归深度不能超过10。铂链会使用WASM字节码作为合约代码应该是参考了EOS的设计,WASM全名为WebAssemly,是一个能被浏览器解析执行的字节码数据,目的是为了解决JavaScript在浏览器中运行过慢的问题。WASM最亮眼的特点就是支持将多种语言编写的程序代码编译为WASM字节码,这其中就包括C/C++、C#、Java、JS等语言。相比于以太坊单一的Solidity智能合约语言,WASM能让区块链支持多种语言编写智能合约代码,这无疑会极大地丰富区块链的应用生态,也是下一代区块链的基本要求。扯了那么多还是罗列下铂链处理智能合约的基本流程:
a) 从交易中取出合约账户、合约方法和合约参数三个数据,判断合约账号和合约方法是否属于内置合约
b) 如果是,则依据合约方法内置的ABI结构解析合约参数,将解析出来的参数传递给对应的内建函数并调用执行,交易执行完毕
c) 如果不是,则依据合约账户从数据库中取出部署在该账户下的合约代码,创建WASM虚拟机并解析合约代码,找到合约代码中的入口函数“Start”和合约方法地址,将方法的地址传入入口函数执行,如果在执行后存在子交易要处理,则回到第一步继续递归处理直到再无子交易或递归深度超过10为止,否则交易执行完毕
铂链的标签就是“DPOS+WASM”,这不禁让人联想到EOS,可能铂链就是在对标EOS,只不过更加关注AI领域,但再造一个EOS真的有意义吗?目前铂链公开的代码还在测试网络中运行,期待后续跟进的Beta版主网代码,可能会有相当大程度的改进,到时候我们再一一解析吧。希望这篇文章能让你更进一步地理解铂链(Bottos)的设计和追求的目标,目前铂链的代码已可在GitHub上下载,上去搜“Bottos”就能找到,如果你对铂链感兴趣,不妨阅读下他们的代码,相信你一定会有所收获的。相比于以太坊和EOS,铂链的代码应该更基础也更容易阅读,对于急切需要了解区块链设计全貌的朋友来说是个不错的切入点。再者,加入铂链社区也是一个了解区块链社区生态的不错的选择,社区里会时不时地发布一些有偿的任务或无偿的培训计划,让社员在社区的激励下逐步了解一款区块链产品。