长安链ChainMaker由北京微芯研究院、清华大学、北京航空航天大学、腾讯、百度和京东等知名高校、企业共同研发。取名“长安链”,喻意“长治久安、再创辉煌、链接世界”。
长安链作为区块链开源底层软件平台,包涵区块链核心框架、丰富的组件库和工具集,致力于为用户高效、精准地解决差异化区块链实现需求,构建高性能、高可信、高安全的新型数字基础设施,同时也是国内首个自主可控区块链软硬件技术体系。
长安链(chainmaker)是 2021 年初发布并开源的一款区块链产品,号称“我国首个自主可控的区块链软硬件技术体系”的区块链。从现有的信息来看,腾讯是这个产品的主要贡献者,代码托管在这里,还有文档在官方文档在这里。
构建基于长安链ChainMaker的数字经济国家主链,以重大场景应用为牵引,构建长安链生态网络,汇集数据要素,增进业务协同,繁荣数字经济新生态。
长安链目前在软件上支持的虚拟机字节码包括两类:WASM(WebAssembly)和EVM字节码。
WebAssembly 有一套完整的语义,实际上 wasm 是体积小且加载快的二进制格式, 其目标就是充分发挥硬件能力以达到原生执行效率。WebAssembly 设计了一个非常规整的文本格式用来开发、调试、测试、优化。
EVM字节码是最初运用在以太坊上的一种虚拟机字节码,目前已经被广泛的运用在许多区块链平台上,有相对比较成熟的开发工具支持。
用户通过高级语言编写的智能合约一般情况而言,都需要存取区块链上的数据、API支持,ChainMaker为不同的高级语言提供了不同的SDK。当然,这些SDK提供的基本能力是相同的,包括读取数据、写入数据、查询区块链的一些状态等。
不同语言的SDK受限于语言本身特性和编译器的支撑能力,比如go语言支持函数同时返回多个数据,而tinygo编译器对垃圾回收支持存在缺陷,加上区块链系统本身为智能合约提供的运行内存大小受限、调用栈深度受限,用户编写合约时,需要注意这些特性。
目前ChainMaker已经支持的智能合约开发SDK包括Rust、Go、C++和Solidity。
长安链自v1.1.0开源版本起支持Solo,Raft,TBFT,HotStuff 四种共识类型。四种共识对比如下:
长安链支持自动发现、自动连接的组网方式,默认在线的每个节点都可以作为种子节点为其他节点提供网络发现服务,每个种子节点都会记录网内节点地址信息。当有新节点连接到某个种子节点时,新节点会向该种子节点查询网内其他可连接节点的地址,拿到其他节点地址后,新节点会主动尝试与这些节点建立连接;另外,种子节点在接受了新节点链接后,会通过网络发现服务将该新节点的地址通知给其他在线的种子节点,其他节点在获得该新节点地址后,也会主动尝试与该新节点建立连接。
长安链理论上可实现上万甚至更多节点同时在线组网。
长安链支持常用的数据库来存储账本数据,如LevelDB、RocksDB、MySQL等数据库,业务可选择其中任意一种数据库来部署区块链。
账本数据主要分为5类:
针对上述5类账本数据,长安链分别实现了5个DB类,分别是:Block DB、State DB、History DB、Result DB和Contract Event DB。采用多个数据库之后,就需要维护数据库之间的数据一致性,避免仅有部分数据库提交后,发生程序中断而导致不同数据库间的数据不一致,因此,长安链引入了Block binary log组件来持久化存储区块的原始内容,用于重启过程中的数据恢复,类似于数据库中的预写式日志(wal)的功能。 需要注意的是,历史数据、结果数据并不是每个节点必须保存的,节点可以根据自己的业务需要在配置文件中启用或者关闭历史数据库和结果数据库。
经过简单的注册步骤,就可以看到长安链的全部代码了。总共有以下这些项目,
chainmaker / chainmaker-common 长安链通用组件库项目
chainmaker / chainmaker-cryptogen 长安链证书生成工具
chainmaker / chainmaker-docs 长安链相关文档,包括:用户手册、运维手册、快速上手指南等
chainmaker / chainmaker-go 长安链底层平台开源项目
chainmaker / chainmaker-pb 长安链protobuf项目
chainmaker / chainmaker-sdk-go 长安链go语言SDK项目
chainmaker / chainmaker-sdk-java 长安链java语言SDK项目
项目的主要代码都在chainmaker-go
项目下,主要的处理逻辑也是在这个项目里面实现,其他都是子项目。
不知道大家看到这个项目结构的时候第一感觉如何,反正我看到这个项目的感觉就是,这不是和 Hyperledger Fabric 一个模子刻出来的吗。稍微看一下chainmaker-go
的代码还会发现,这个项目真的和 Fabric 相似度地方太多了,比如:都有 cryptogen
程序;都有管理智能合约生命周期的智能合约;都有一个叫solo的共识算法用于测试;chainmaker-go
项目的目录结构和 Fabric 也很相似;还有,Fabric 标志性的 Policy 机制在长安链项目中也出现了。诸如此类,不一而足。
对两个相似功能的代码结构做比较,得出“两者有相似性”这样的判断可能有些主观。可以另外比较一下,长安链和以太坊(ethereum)的代码,长安链和Corda的代码,多比较几个区块链项目的源码(不用看代码,只看源码结构就好),能得出相同的结论。
当然,单纯的代码结构相似,也不能抹杀长安链项目本身的创新。毕竟 Fabric 在联盟链领域已经有了相当的市场份额,设计上、功能上、代码实现上必定有些过人之处,后续的项目在某些方面借鉴一下也无妨。
仔细查看一下代码的话,发现chainmaker-go
在某些接口定义上还是有些和 Fabric 相似,但不相似的地方随着看的深入也更加多起来,慢慢的也不那么像 Fabric 了。
长安链应该被定位为一款联盟链产品,而非公有链,或者公有链改出来的联盟链产品。长安链从诞生之初就是联盟链,这与国内其他的区块链开源项目是不同的,目前国内开源的联盟链,如 bcos、fisco 等,都是基于以太坊(公有链)项目的修改,在设计上有很多公有链的痕迹。国内也有一些基于 Fabric 修改的联盟链产品,但要么是暂时尚未开源,要么是开源了,但并不活跃。
因此,笔者会站在联盟链的角度,尝试去理解并分析长安链的设计,从技术设计的角度,评价这些设计的优劣。先说好的,再说中等的,最后说不好的,有些地方会和 Fabric 做一些对比。
公有链:访问门槛低,数据公开透明且无法篡改,匿名性,免受开发者影响。
特点: 人人可以访问,读取,公开透明,完全的去中心化。就好比你大过节的秀恩爱,发了一条朋友圈,所有人可见那种。 典型代表就是比特币,以太坊。
私有链:权限设计要求更复杂,可信度更高。对单独的个人或实体开放,仅在私有组织,比如公司内部使用。就好比失恋的你大半夜发朋友圈,仅自己可见那种。典型代表Linux基金会项目。
联盟链:由多组织共同参与管理,隐私保障良好,交易成本低,速度快。介于公有链与私有链之间的一种形态,部分去中心化,参与者可能是提前预定或者直接指定的。就好比朋友圈想发点一个圈子的图片,屏蔽其他圈子认识的人,只给好基友们看那种。典型代表R3区块链联盟(国际银行和金融机构合作组织)。
这一点刚才提到了,整体上,长安链是联盟链的设计。比如,长安链的共识机制主要包括solo、raft、tbft,还有将在 1.1.0 发布的 chainedbft(类似HotstuffBFT)。这些都是联盟链会使用的共识算法,没有提供 PoW、Pos、DPoS 这类公有链的共识机制。再比如,长安链的数据存储采用了 KV 模型,没有采用公有链的账本模型。还有,长安链提供了身份、角色、权限管理机制,而公有链不会有这些功能。
以上这些标志性的特征,都说明长安链的联盟链属性非常重。
Policy 机制应该是由 Fabric 最早引入到区块链里面来的。这套机制是建立在身份认证(本质是数字证书机制)之上,用于权限管理功能的。长安链引入了这套机制,具体的设计思路和 Fabric 毫无二致,但做了实用的改进。
Fabric 的 Policy 可以支持复杂的权限定义表达式,例如,“OR(org0, AND(org1, org2))”,多层嵌套,造出复杂的权限定义。长安链的 Policy 机制只支持简单的表达式,并且不支持嵌套,例如,
policy{
orgList: []string{"org1", "org2", "org3"},
roleList: []protocol.Role{protocol.RoleAdmin, protocol.RoleClient, protocol.RoleCommonNode}
rule: protocol.RuleAll,
}
这个配置类似 Fabric 的“AND(org1, org2, org3)”,虽然长安链的表现形式长了,但技术实现上相比 Fabric 要简化一些。这个简化是有益的,现实场景中,需要支持嵌套的场景真的是太罕见了,这个改进会简化一些代码实现。过早的支持一些特殊场景,只会带来代码的复杂,并没什么用。
此外,长安链在角色分类上更加细致,定义了4种类别;Fabric 只有2种类别。长安链多出来的是 CONSENSUS 和 COMMON。还有,长安链在规则上,也多了一些,如分数规则和禁用规则。虽然这些改进比较简单,但是不失为一种有益的尝试。
有些地方没法和 Fabric 完全对应上,比如 Fabric 有 OrderOrg,可以用来区分 CONSENSUS 角色。此处仅做表面的比对。
长安链的 Policy 机制还略有一些不足,比如,Policy 配置还不是很清晰,rolelist中的规则默认是“或”的关系,即任何一个rolelist中的角色签名即可。但上述例子会让人误解成,是需要org1的ADMIN,org2的CLIENT,org3的COMMON来签名吗?再比如,Fabric 可以构建OR(org0.member, org1.admin))
这样要求不同机构角色签名的场景,目前长安链也无法满足。但这样的应用场景应该也比较少。
瑕不掩瑜,长安链对 Policy 机制的改进,是有可取之处的。
在长安链的文档中提到了证书压缩机制,如下,
// Serialized member of blockchain message SerializedMember { // organization identifier of the member string org_id = 1; // member identity related info bytes bytes member_info = 2; // use cert compression // todo: is_full_cert -> compressed bool is_full_cert = 3; } * ChainId:链标识,表名本交易是针对哪条链的,防止一个交易在多个链中被打包。 * Sender:交易发送者信息 - OrgId:成员所属机构编号 - MemberInfo:成员的身份信息,可以是证书信息也可以是证书标识,依赖于IsFullCert字段 - IsFullCert:是否为全量证书,如果是,则MemberInfo填写用户证书的信息;如果不是,则MemberInfo填写用户证书标识(该标识需通过证书上链接口提前在链上登记)
主要就是SerializedMember
中的IsFullCert
和MemberInfo
两个字段。文档的内容已经说的很清楚了,SerializedMember
是存储成员身份信息的结构,当IsFullCert
为 true 的时候,MemberInfo
中存储的是完整的证书信息;当IsFullCert
为 false 的时候,MemberInfo
中存储的的是证书的标识(实际是哈希),证书本身已经提前在链上登记。哈希占用的存储空间当然比一个完整的证书要小多了,因此也达到了减少存储的作用。当然,多数情况下,长安链会采用压缩机制。
这个改进是100%有效的改进,降低了IO资源的消耗,尤其在交易本身内容比较少的时候(证书存储占比较高),改进特别明显。本来,这个可以是长安链中非常原创的改进,可惜,在某个未开源项目中已经了解到过与此几乎相同的设计,因此没有把这个特性放在首位。
Fabric 修改链配置的步骤是比较复杂的,需要在当前配置块的基础上,计算出修改造成的差值,对修改请求签名,然后再进行修改。长安链是通过执行内部智能合约的方式来修改,具体是通过定义一种特别的请求类型TxType_UPDATE_CHAIN_CONFIG
来实现。这个方式比 Fabric 的要简便一些。
Fabric 的修改方案虽然复杂,但是可以任意的修改,自由度大;长安链受限与智能合约提供的方法,只能进行部分修改,但通常情况下也足够用了。
实话说,Fabric 修改配置碰到的问题还是挺常见的,很多项目都有这样的痛点,长安链的这个改进是有益的。
当然,Fabric 原生并不支持国密算法,我估计很可能“永远”也不会添加这个特性。但是国内的区块链项目,如果没有支持国密,能支持的业务场景又会受限。因此,国内的基于 Fabric 修改的联盟链产品,基本都提供了国密算法的支持。
以长安链的背景,不支持国密是不可能的。密码这部分代码我都没有细看,但我相信,一定支持。
这个特性本来我想放进下一个章节的,仔细思索,还是留在了这里。我一直觉得,项目早期阶段并不需要智能合约多引擎,多语言的支持,尤其是多语言。
因为,能用一种语言来写合约已经足够了,相同的逻辑支持另一种语言来写,实际没什么意义,智能合约里面并没有那么多复杂的逻辑来写,也几乎不存在一种语言能写出来,另一种语言写不出来的功能。至于智能合约引擎,多样化的需求会相对多一些。但实际使用时,一般都是在能用的引擎里面找一个稳定性和性能都比较平衡的一个,多数情况也没那么多选择。
长安链在初次发布的时候,就支持多引擎、多语言,在 1.1.0 版本中还加入了evm支持,感觉是设计的时候搞错了重点,没有把全部力量集中在做精产品,而是在求大、求全。多引擎、多语言应该是产品的能力已经得到充分的证明的情况下,在扩张其他场景的时候才需要考虑的功能。
话说回来,虽然我觉得这个特性引入的时机并不恰当,但其本身并不是坏功能。至少在产品推广的亲和力上会好很多,考虑到不同背景的区块链开发者,支持多种智能合约语言会降低开发门槛。