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

阅读数:713 2018 年 12 月 14 日

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

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

image

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

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

易用性有以下三个方面:

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

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

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

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

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

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

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

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

下图为 CBaas 平台的技术栈:

image

因为区块链的部署(尤其是 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 网络、共识引擎、智能合约执行引擎、底层数据账本,以及联盟链独有的权限体系。

image

我们首选 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 消耗。

image

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

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

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

image

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

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

优点:

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

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

缺点:

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

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

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

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

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

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

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

  1. fabric 模块化设计之共识引擎的解耦

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

image

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

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

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

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

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

image

  1. 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 中某个过程中的权限控制。

image

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

image

  1. Fabric 对于同构链中多链以及多链通信的设计

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

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

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

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

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

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

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

image

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

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

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

image

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

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

image

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

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

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

image

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

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

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

作者介绍:何鑫铭,携程技术中心创新研发部区块链技术专家,携程区块链技术平台技术负责人,精通当前主流区块链开源技术框架,热衷于研究区块链底层设计和区块链应用创新。本文来自何鑫铭在“2018 携程技术峰会”上的分享。

收藏

评论

微博

发表评论

注册/登录 InfoQ 发表评论