如何在分布式体系中做架构设计? |《超话区块链》回顾

Date: 2021-08-09 Source: 本站



本篇是基于柏链教育公司、上贸大研究中心团队、柏链教育系里面成员、以及我在FISCO BCOS上进行的联盟链方向探索的经验分享总结,希望给大家带来启发及借鉴作用。 

这次分享的主题分为4个部分:第一是谈谈分布式体系架构特点及差异,第二是谈谈如何进行链上与链下的设计,第三是谈谈如何对服务端与客户端进行设计,第四是总结我们目前在实践过程中遇到过的分布式体系。

在传统应用软件系统的开发里,常常会提到最佳实践。对传统软件系统来说,经过多年的发展,其可以说是最佳实践,但对区块链技术来说,包括我们在内的所有人,其实都还处于摸索的阶段。

现在的区块链行业相当于90年代的计算机行业,正处于我称之为相对最佳实践。欢迎大家一同加入,共同就系统设计进行深入探讨。

分布式体系架构与传统架构的差异

传统思路下的证书系统设计

传统思路下设计的是中心化的证书系统,该系统包含三个必要部分,分别是前端、后端和数据库。

前后端可能会包括许多服务,这些服务均被主体所掌控,即中心化系统。这个中心化系统指的是服务管理主体上的中心化,从技术上来说一个传统中心化系统也可以是分布式架构。

在中心化系统里,我们定义三类角色,分别是权威发行者、用户和验证方。

权威发行者,比如一所大学,它可以给学生发放证书;用户不仅可以接收权威发行方所发行的证书,还可以向验证方提交他所拥有的证书;验证方在收到用户提交的证书后,可以验证证书的有效性。

传统思路下的证书系统具有如下特点:

首先,数据库中的ID具有唯一性,而唯一性是有限制范围的,它的使用范围不会超出所在的数据库。

其次,权威发行方、用户和验证方之间的交互都要经过中心化系统。比如,权威发行方无法绕开中心化系统给用户发行证书,验证方也不能绕开中心化系统验证用户发的证书。一旦中心化系统出现问题,所有的角色将面临无法使用。

区块链思路下的证书系统设计

在区块链思路下,设计证书系统可能用的是现成的区块链网络,也可能是特意创建的区块链网络。为了方便传统开发者理解,我们很多时候将区块链视为具有开放特性的由许多节点维护的公共数据库。

由于公共数据库的存在,服务可以不再限定某一家公司部署,比如证书发放服务A由柏链教育提供服务,同时另一家公司也想提供服务,于是在开源基础上对系统进行优化改造。它也具有节点的访问权限,这两个发布服务的数据都会流向公共数据库。之后具有权限的第三方也可以访问公共数据库。

所有的服务并不由一个主体来发行,这种设计一方面增加了服务的复杂性,但同时也带来了许多想象空间。

全链唯一数字身份

我们在设计普通应用时,ID的作用域是整个应用 ,所以只要确保全应用唯一就行了。

在区块链应用中,用户的ID可以直接与区块链网络相连,它可以拥有全链唯一的ID,即Weldentity数字身份(DID)。这个改动意味着现在ID扩大了范围,是全链唯一。

分布式架构与传统架构之间的差异

了解以上信息,我们再将分布式体系下的证书系统与传统的证书系统进行比较,主要差别表现在:

第一,软件的生命周期。在传统体系下,服务的生命周期通常小于公司的生命周期;而在区块链思路下,生命周期表现出复杂的特性。区块链的生命周期取决于所有参与者。

此外,这些服务之间的生命周期也存在差异,例如证书验证服务是由个人开发的,如果我单独写证书验证服务连接到数据库中,那么即使提供服务的公司都倒闭了,我的证书验证服务依然可以用。所以不同主体所部署的服务,其生命周期是相互独立的。

第二,提供更多的选择。传统系统下,我们的选择就是中心化系统,它是否升级完全取决于中心化系统主体的意愿。而在分布式系统下,服务之间存在着竞争关系。假设联盟链中有A、B、C三家公司共同提供服务,大家自然会倾向于选择提供更好服务的公司。

因而在参与主体足够多的情况下,新的系统内部其实存在着竞争机制,人们在多个服务提供商之间进行选择,激励大家去提供更优质的服务,促进整个证书系统市场化发展。

第三,不同的数据处理方式。在传统系统里,即使数据库使用分布式系统里的分片,但从本质上来看它仍然是单一数据库,我们不需要考虑数据在哪。而在区块链系统下,我们就需要思考不同的数据究竟需存在哪个数据库里,哪些数据需要进行上链处理之类的问题。

第四,交互方式不同。传统思路下,所有的参与方如果想要和另外的人员进行交互必须经过中心化系统。但是在新的证书系统下,用户只要在提交给验证方之前获得了权威发行方的公钥,就可以去验证证书,双方之间实现点对点交互。

如何进行链上与链下设计

在进行链上设计时,首先要善用CNS对合约进行版本管理。不同的版本之间,我们会用不同的版本名称来区分,例如1.0、2.0。这样既能使合约更加直观,也能减少在此过程中出现 bug 的可能性。

其次,要对合约进行分层,将数据层和数据操作层进行分离。合约需要优化时,如果所有代码都写在一个文件里,那升级时可能还得对过去的数据进行迁移。但现在合约分层以后,存储的数据不用改动,也不用去做数据迁移,我们就可以直接对合约进行升级。

除了CNS和合约分层以外,还要坚持“胖链下、瘦链上”和“抽象链上、具象链下”的原则。因为链上其实是很重的,我们把数据存在链上,也在链上进行计算操作。例如,当我们在链上计算“1+6”,那么链上的每个节点都要执行一次,比起链下运行,负担加重了很多。

在区块链上进行数据存储,有多少节点就存储多少次,存储的负载就是节点的数量;在区块链上进行计算操作,所有节点都需要计算一次。

因此,我们要精简链上合约的逻辑,在设计合约时要全面思考关键问题——操作是不是必须要在链上进行执行,数据是不是必须要在链上进行存储,开发者得计算出存储和计算成本最小的合约。

像“1+6”这样的日常计算,这类操作即无需放在链上执行。另外,存证时有时会写太多具体的业务字段,这其实是违背了“抽象链上、具象链下”的原则。因此,我们在设计合约时,会提出合约要具备更高通用性的要求。

那么,存证就应该是哈希上链吗?事实上,这种说法存在一定的武断性。在实际的业务操作中,它取决于具体目的。

假如我们做的是司法存证这种业务场景,哈希上链就很合理,因为司法存证的目的是要检查原始数据是否与链上哈希值一致。

但如果是出于其它目的,例如我们想要将运营数据真实地存储在链上,业务操作中会将json转换成string再去存储在链上,而使用哈希则达不到目的。

如何对服务端与客户端设计

第一种,纯服务端。这是比较轻松的选择,因为它与传统的思路极其相似。譬如我们要做区块链版的知乎,简单、取巧的方式就是去做支付网站,然后访问的时候只有客户端。这种方式比较保守,也不容易出错,适合于做最开始的尝试。

第二种,轻客户端加服务端的形式。本地如要获取、存储用户的私钥,在服务端传来未签名的交易时,请客户端签名后再发送回给服务端。这样的设计其实是在第一步的基础之上,谨慎地迈出分布式的新尝试。

第三种,重客户端加轻服务端的形式。如果要设计数字身份钱包,基于Weldentity的系统其实就可以采取客户端的形式,而新的服务端就仅起到转发作用。

这样的形式会比较大胆,因为它把更多的功能转移到了客户端这边,这种方式的采用取决于实际业务需求。就经验而言,一开始还是不要做过于创新的设计,因为很容易出现问题,谨慎为好。

分布式体系中的架构总结

第一个例子是基于Weldentity的证书系统。可以有两种选择,一是用户调用服务器端的证书管理服务;二是本地下载了客户端,客户端有专属管理的业务。

这其实是很有意思的一种玩法,用户的证书管理服务既可以是在自己的电脑上,也可以使用某个机构在云商部署的证书管理服务。



第二是基于 WeBASE的设计。我们可以把WeBASE作为节点前置的一套组件进行区块链接入,把私钥托管在这上面。通过这种方式我们可以节省很多事情,可以利用WeBASE高效地实现区块链应用。



第三是区块链存证系统。我们在WeBASE前加了链下中间件,对于存证的内容进行格式验证。这些Application 提供的存证内容,需要验证通过才能上链。

还有公开查询服务。事实上,很多区块链系统都有这样的需求,需要提供部分数据的公开查询服务。




《超话区块链》
《超话区块链》是由FISCO BCOS 开源社区推出的直播活动,每周四晚8点,社区邀请一位技术极客或应用先锋,做客直播间分享开发实践或应用心得。作为社区固定栏目,《超话区块链》已举办近百场,从技术研讨到产业应用均有触达,欢迎大家自荐或推荐朋友到直播间分享。添加【小助手】微信入群观看直播。