查看原文
其他

干货 | HyperLedger Fabric在携程区块链服务平台的应用实战

何鑫铭 携程技术中心 2019-05-01

作者简介

 

何鑫铭,携程技术中心创新研发部区块链技术专家,携程区块链技术平台技术负责人,精通当前主流区块链开源技术框架,热衷于研究区块链底层设计和区块链应用创新。

本文来自何鑫铭在“2018携程技术峰会”上的分享。


一、在业务应用区块链技术之前,我们需要做什么?

       

在主题介绍之前,一起来看一张图:



上图是Gartner提供的一份2018年关于企业对区块链技术规划的调研结果,结果表明在受访的企业中(包含高科技、IT、互联网企业)大概有66%的企业表示对区块链技术感兴趣,但是真实投入研发并且在正式环境部署过的企业大概只有1%。


区块链技术还未发展到或者人们还没有认识到其所带来的价值和意义,这是现状。其中一个原因是——这个技术的易用性现在是很低的。


易用性有以下三个方面:


1、开发、部署、运维成本高;


2、公有链、私有链、联盟链框架众多,且技术标准还未形成统一共识;


3、各个企业缺乏工程落地经验,各个行业更是缺乏应用落地范本。


现在区块链技术所处的阶段,个人理解像是web技术发展的早期,还未形成统一的web技术核心标准(如http协议等),所以也就没有太多的web应用创造出来。


携程作为国内互联网旅游行业的领军企业,非常重视技术对于业务的创新推动,最近一年我们在非常积极的进行技术研究,以及技术应用的创新。


我们发现,即使是最成熟的如Fabric、以太坊这样的开源技术框架,也远远没有达到生产环境对于稳定性、高可用性、高并发支持等这些基本要素的要求,而这些框架的学习成本、使用成本、运维成本也非常高,让现有的业务部门技术同事兼职来现学现用,是一件非常困难的事情。


因此,需要做一个支撑业务应用的区块链服务平台,去屏蔽掉最底层区块链系统的网络架构、框架搭建、应用集成、运维监控的复杂性,并且需要做各种源码、环境、使用方式的优化,以让上层业务应用能最高效的应用区块链技术。


平台的目标是各个业务部门的技术同事在充分了解区块链技术理念、基本概念以及如何解决业务痛点的前提下,能够不深入学习以太坊、Fabric等底层区块链技术框架,就能快速将当前业务与区块链技术结合。包含快速开发、快速部署、快速上线、有效运维以及能够满足对于应用上线的基本要求。


二、携程区块链技术服务平台(CBaas)介绍


下图为CBaas平台的技术栈:


       

因为区块链的部署(尤其是fabric)对于容器技术是重度依赖的,所以需要一个可应用于生产环境的swarm/k8s集群服务。


这样的区块链平台,与独立的业务系统是完全不同的,而更像是集开发、发布、测试、运行、运维于一体的完整的应用操作系统。对于我们现有的应用发布、运维体系有较大冲突,需要paas层服务团队提供更为灵活的支持。


上面一层是区块链的底层框架,首选支持的是目前最为成熟的联盟链框架-HyperLedger Fabric,Fabric目前在国内外是落地最多的框架了。其次是以太坊,以太坊是区块链2.0即智能合约平台最重要的框架,其影响力和社会熟知度是比较高的,以太坊更适合做激励型社区类应用。最后是我们正在做的自己的底层区块链框架CtripChain。


在应用Fabric的时候,我们改了一些或者说是扩展了一些框架的源代码。Fabric是一个在技术、代码设计上非常灵活的框架,因此我们将改动抽象出了代码上的一个插件层,如国密算法、PBFT共识等。


服务层是CBaas平台的主要逻辑所在,我们将Fabric等这些框架在更上层抽象出了网络、联盟、通道、节点等概念。


可以通过CBaas console页面,你灵活的根据自己的需求搭建区块链技术架构,进行动态节点扩容、动态对链进行治理等。


值得一提的是,我们改变了传统的baas平台集中式、上帝式的区块链治理模式。


我们认为,联盟链不应该是由一个组织、一个用户来进行治理,引入了多企业租户共同治理的模式。比如一个既有通道、既有联盟增加新的企业成员,应该由通道/联盟中的组织一起进行签名审批,并且将签名审批结果提交到链上,与链上策略模块提前在线上协商制定好的背书策略签名一致才可以通过。


整个过程中,所有企业在平台上都是一个独立的企业租户,甚至可以将企业租户对应的节点,部署到自己的内网中。只要保证与企业联合建立的联盟网络能够进行rpc通信就可以。


服务层其他方面,一个是公链的锚定,这与业务有一定关系。在做区块链创新的过程中,我们也跟业内有名的区块链公司合作,将联盟链上的一些东西,跟公链做hash锚定,来进一步增强联盟链的公信力。


另一块是api service,进一步对fabric、以太坊等区块链的客户端SDK进行了封装,业务开发人员可以直接调用CBaas平台上的restful接口来进行合约的调用,甚至是联盟、通道等动态治理。


最后是我们定义的区块链的“前端”展现端,这块包括portal工作台、外部节点安装包、OpenAPI,区块链浏览器(可以用于汇报展示用),以及内部的一个智能合约集市,一些比较好的智能合约可以共享在集市上。


三、联盟链框架的选择——HyperLedger Fabric的架构与设计理念


在做CBaas平台选择支持的底层框架时,我们对于Hyperledger Fabric的代码研究的一些经验,希望可以给大家在做联盟链底层技术选择时一些参考。


下面是Hyperledger Fabric的整体组成,也是当前主流区块链2.0技术框架的通用型架构,包含client SDK、p2p网络、共识引擎、智能合约执行引擎、底层数据账本,以及联盟链独有的权限体系。



我们首选Fabric框架,除了其社区活跃、落地应用案例较多外,另一个比较重要的因素是它的模块设计非常灵活,体现在技术设计、代码模块设计上。


1、fabric模块化设计之合约执行引擎的解耦


首先看一下fabric在合约执行引擎层的解耦,我们做一个fabric与以太坊的对比。


以太坊的evm定义了一个适合在公链网络中可以在以太坊节点上运行的简单、确定、轻量、安全并且能够计算合约运行成本的智能合约虚拟机。是首个在区块链网络上支持智能合约运行并取得成就,且到目前为止,没有因为evm的bug导致重大事故发生(目前出现的事故都是合约代码的bug)。


当然,evm的设计并非没有缺陷,evm存在的问题:


1)账本数据结构与evm代码绑定较深,修改会互相影响。


现在很多机构自研的公链/联盟链,选用的智能合约执行引擎大多都是evm,如果不加以较为大量的源代码修改、测试,基本意味着底层账本的数据格式、结构都是以太坊的了。当然这个问题在未来也有可能不是问题,前提是evm能作为智能合约引擎以及底层账本的技术标准。


2)采用256位整数运算,致使32位/64位x86处理器相对低效。


这其实是为了适应更大的内存寻址和复杂的密码学运算以实现安全的gas模型而设计的,但是当evm被用于联盟链时,这种低效的处理是完全没有必要的,因为联盟链无需消耗gas。


3)evm是一个基于栈的虚拟机,大多数操作都使用栈。


栈都是有栈深度的,意味着当使用超过栈深的时候就会报错栈溢出。


4)evm的标准库太少。


这个一方面跟solidity的语言生态有关,另一方面是因为如果引入大量的第三方库,可能会意味着引入不必要的代码和gas消耗。



关于evm的问题,这里不深入探讨,网上很多技术大牛对evm缺陷有更深入的分析。再来看一下fabric,fabric有两块设计来做智能合约执行引擎解耦:


1)在代码层面,定义了container接口层,该接口目前有3个实现:DockerVM(执行用户合约)、InproVM(执行系统合约)、MockVM(UnitTest的mock环境)。


目前fabric的智能合约引擎可以理解为是基于docker容器的,当节点主应用部署一个智能合约时,会socket连接节点宿主机的docker,动态生成一个可以执行智能合约语言的docker容器。这是fabric自带的一个实现,因为fabric在这块是代码解耦的,意味着可以实现该接口来实现自己的智能合约执行引擎,如jvm等。



2)DockerVM的实现中,docker容器与区块链节点的通信方式为grpc,意味着通过协议的模式进行了代码层的解耦。这与以太坊中evm代码与节点代码难以解耦不同。


我们总结了fabric以下优缺点:


优点:


1)代码层面上实现了对VM和节点进行脱耦,并且易于扩展新的VM方式。


2)dockerVM的原理,理论可支持众多开发语言开发智能合约。


缺点:


依赖docker运行环境,严重限制fabric节点的部署可能性;docker作为沙箱环境相对复杂,安全性、稳定性都面临较大的挑战,难以适用于公链环境,但是可以应用在一个确定运行环境的联盟链上。


2、fabric模块化设计之链上代码逻辑的解耦


这一点我觉得是fabric明显优于现在的区块链2.0众多联盟链框架的地方,也是很多区块链3.0,如EOS等正在做的东西,那就是——将更多主链上的逻辑(非用户开发的智能合约)作为链上的事务,或者是作为链上的智能合约来设计。


这就意味着,首先链上的逻辑可以更灵活的被修改甚至可以在不需要在有可能引起分叉的代码升级的前提下进行运行时修改;再就是链上逻辑的修改可以像智能合约一样,被共识。


Fabric将节点代码中的部分逻辑,如背书过程、交易验证过程、智能合约生命周期管理、配置管理(对应escc、vscc、cscc、lscc系统链码)都作为链上合约来设计,称之为系统合约。


这些过程是可以被链的共识机制所覆盖的,所以才有了fabric可以通过定义各种策略,来实现非中心化地干预这些内置处理流程,如可以定义背书策略、智能合约初始化策略等。


不过现在fabric1.3的版本并没有做到链上的逻辑可以被灵活修改甚至是运行时修改,到现在只是开放了开发者可以通过代码替换来自定义修改escc、vscc。现在的开发者可以通过修改这两个系统合约,实现很多fabric目前实现不了的功能,比如:基于数据状态的背书策略、匿名交易场景(公钥匿名)等。


3、fabric模块化设计之共识引擎的解耦


我们先来回顾一下fabric的共识过程:



其实fabric的共识过程是比较有自己的特点的,跟公链的共识过程也有比较大的不同:公链的共识者,同时承担合约预执行、交易排序的职责;fabric中排序节点只做排序,合约预执行由背书节点做。(fabric中背书节点与排序节点的组合=公链如以太坊中的共识节点)。


不过,fabric在共识这一块的解耦是跟智能合约执行引擎比较类似的做法:


1)排序节点代码侧定义了consenter接口,可以通过实现consenter接口拓展共识排序算法.


2)刚讲了fabric的共识要算上背书节点背书和交易验证模块,对应escc/vscc两个系统合约,恰好这两个系统合约是可以修改的。


以下附录这一点的完整总结。



4、fabric模块化设计之权限控制的解耦


权限控制其实作为联盟链重要的特征,在fabric中体现的淋漓尽致,我们来看一下fabric是如何做整个链上的权限控制的呢?


在设计常规的多租户企业级软件时,我们往往都会先定义软件的使用企业、企业用户、系统角色,再定义每个页面、菜单,然后再将企业、用户、角色与页面、菜单结合起来,这样就可以设置哪个企业、什么样的用户、什么样的角色有权限访问某个页面、菜单……


其实fabric的设计与这种企业软件的设计类似,首先fabric中权限的最高级别是msp,msp可以是一个组织,如org1,用来做整个区块链的企业租户切分,msp之下,fabric又定义了用户、节点,组成权限体系的角色role层级。如:Org1.admin、Org1.member、Org1.peer。


而组织,包括组织下的用户、节点等都有一个唯一的ID,这个唯一的ID在区块链中成为identity(以太坊的identity比较简单,它是一个公链所以identity只代表用户),每个identity基于非对称密码学对应一对公私钥。


区块链在运行时,全靠这个identity来标识身份。fabric有一个子项目叫fabric-ca,提供这个identity的管理机制,即一套PKI公钥基础设施。


fabric将很多链上的过程,都定义成了上面所讲的企业软件中的“功能”,而功能与角色或者ID的对应访问关系,叫做“ACL”。


现在比较好理解了吧,其实ACL就是企业级软件中的哪个企业、什么样的用户、什么样的角色有权限访问某个功能。以下截图是部分fabric中现有的ACL,我们可以通过修改这个ACL,达到修改fabric中某个过程中的权限控制。


 

以下附录这一点的完整总结。



5、Fabric对于同构链中多链以及多链通信的设计


这一点是有别于前面三点的,前面三点都是说明fabric是如何做技术设计的解耦。而这一点我们聊聊fabric对于同构链中多链以及多链通信的设计。


首先解释一下什么是多链问题,我们知道,其实我们所熟知的以太坊、比特币主链其实都是一条比较大型的公有链。而其实除了主链外,基于比特币、以太坊源码有很多机构自己重新搭建的一条新的链。


比如同样的两条以太坊搭建的链,就说明两条链是同构链,而两条链之间如果需要通信,就是同构链的通信,也就是多链通信。刚刚讲的只是多链的一部分形态,还有侧链、子链、平行链等更多多链形态,为大家容易理解,不做赘述。


对于fabric,首先它定义了通道的概念,即一个fabric联盟链网络,可以有多个通道,每个通道对应本地一套单独的账本,这个通道可以理解为一个类似于子链的概念。


我们可以把每个通道,看成是一个较为独立的子链,这个子链的账本是物理隔离的,不过每个子链需要共享父链的排序节点。


目前fabric中跨通道的通信,是通过智能合约间的调用实现的,如同时在channel1/channel2上的节点安装的合约1/合约2可以互相调用,即两个通道只有在存在交集节点的情况下,才可以通信,还未实现完全独立的通道之间的数据互通。


fabric中通道的设计其实可以做很多远远超过你预期的事情,如隐私数据保护、缓解节点数据无法分片问题、实现并行计算支持高并发。


      

四、fabric在链上保存原始数据(非哈希)并可以按需分享的一种解决方案


下面分享我们在fabric应用过程,这个分享标题完整版为:在保护数据隐私的前提下,如何用fabric在链上保存原始数据(非哈希)并可以按需分享的一种解决方案。


首先来看一个区块链应用的场景:



如A与C,B与C分别在发生交易,但是A和B是同业,互相不希望与C发生的交易被彼此知道。所以放到fabric中,大家肯定要分别设计两个channel,来屏蔽两个交易方,通过channel可以做一些交易对手间的信息共享。


而这个时候假设存在D,在实际业务中有权利查看AC和BC的全部业务数据,则D可以分别加入到channelA,B中。这个模型是没问题的,那我们现在把问题变复杂一些。



OrgD假设是没有权利查看AC、BC所有交易的权限的。但是在实际业务中,他希望可以看到AC、BC的某些交易详情,且需要经过A/B的授权才可以查看,该怎么办?


这个时候有同学可能会讲,A和B分别把他希望的数据给他不就可以了吗?我们这里有个前提,就是我们需要借助区块链这个技术,直接将数据在链上给过去,因为这样数据可以经过交易对手方C组织的背书,假设D能够直接从channelA、B上拿到他想要的数据,那么这个数据是天然经过C组织背书的。


我们来看这样一个解决方案:



这张图已经完整的描述了整个方案的详情,以及这个方案的优点:整个交易过程全部上链,不引入链下的过程,实现数据、信任完全的链上流转。这个案例经常出现的业务场景想必大家已经猜到了,就是金融领域。


也许真实遇到的业务场景要比我上面举的例子要复杂的多,也许还有更好的解决方案,如很多人提出一个零知识证明的算法,但是之所以将这个例子拿出来交流,其实是希望每一个从业者能从“哈希上链”这样一个保护伞下中逐渐走出,去尝试克服真实数据上链的各种难题,从而使区块链技术真正地服务于实际业务,让业务数据能够真实的在链上互转,真正成为“信任机器”的主角。


希望在各位同道的一起努力下,区块链技术能够真正走出实验室、走出技术极客的圈子,发挥出技术应有的价值。


2018携程技术峰会PPT和视频可见这里


【推荐阅读】





    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存