Hyperledger Fabric解密之架构篇

国务院“十三五”国家信息化规划中明确提出区块链等新技术正驱动着现实世界与数字世界的交汇融合,全球治理体系面临深刻变革。Hyperledger Fabric是Linux基金会开源的区块链子项目,自2015年诞生之日起就受到了众多国际知名企业的密切关注,是目前业界主流的区块链开源项目,先后推出了V0.6和V1.0两个大版本,接下来就让我们一起揭开Fabric 1.0架构的神秘面纱。

1、

区块链简介

为了能加深理解,在剖析技术之前,首先简单介绍一下什么是区块链。

区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码学方式保证其不可篡改和不可伪造的分布式账本。

区块链的最显著特性就是,在去中心化的前提下建立组织之间的信任机制,并有望在未来重塑商业模式。如下图所示,传统的系统模式一般由第三方权威机构搭建一个中心化应用给其它组织使用,由权威机构提供信任保证;区块链的系统模式,是由参与方共同构建一个分布式应用,使用集体共识的方式提供信任保证,全网络共同维护一套账本。

区块链发展至今,经历了1.0(比特币时代)到2.0(智能合约时代)的变迁,诞生了“智能合约”这一2.0时代的区块链“灵魂”。智能合约,将业务参与者的业务协议规定翻译为代码,嵌入到区块链中,满足一定条件后,可以由区块链网络自动执行。智能合约的出现,让区块链真正从比特币时代走出,广泛应用于金融、征信、医疗等各行各业。

接下来分别从动静两方面,一起来看看Fabric将如何实现区块链的核心理念和特性。

2、

静态剖析——Fabric总体架构

Fabric1.0采用了可插拔的模块化架构设计理念,模块间利用gRPC协议、抽象接口等方式充分解耦,一个模块内的修改不会影响其它模块的功能。也就是说,开发者也可以根据自己的需求做定制化开发。

其总体架构可以分为以下4大模块:

1)客户端SDK模块:

Fabric提供了封装API接口的SDK供应用端调用。应用端可以通过SDK访问Fabric网络中的多种资源,包括账本、链码、事件、权限管理等。应用开发者只需要跟SDK打交道即可,无需关心如何实现和管理这些资源。Fabric已经拥有了多种语言的SDK包括node.js、python、Java、go等多种实现,可以提供更完善的客户端和开发支持。

2)核心实现模块:

核心实现模块中最重要的子模块是账本和链码。使用大家熟悉的关系型数据库做类比的话,账本相当于存储数据的表,链码相等于存储过程。

账本用来记录业务信息,应用则通过发起交易请求来向账本中记录数据。账本实现了区块链的基本链式结构,以及数据不可篡改、可溯源的基本理念。账本依赖核心的区块链结构、数据库、共识机制等技术,其物理存储结构目前支持LevelDB和CouchDB。

交易执行的逻辑以及对账本的读写都通过链码来承载。链码实现了区块链的智能合约理念,业务参与者可以通过事先定制链码将业务协议电子化,从而驱动业务的执行。链码依赖容器、状态机等技术,运行在docker容器内,编程语言目前支持go和java语言编写。

核心实现模块还提供对整个网络运行中发生的事件的监听,应用可以通过注册事件来触发外部流程。

3)安全模块:

采用主流的PKI体系,利用数字证书、加解密算法等诸多安全技术,实现对不同资源进行基于身份证书的安全认证。

4)网络模块:

Fabric底层由多个节点组成P2P网络,通过gRPC通道进行交互,利用Gossip协议进行节点间同步,支撑整个分布式区块链网络的联通与运行。

核心实现模块运行于网络模块之上,二者的有机结合提供了整个区块链网络的基本功能,是Fabric对区块链去中心化分布式网络体系的具体实现。安全模块为区块链网络的通信提供基本的安全认证,同时也为所有的通信消息内容提供了不可抵赖的数字证书签名机制。而在此之上,客户端SDK作为区块链网络的对外延伸,对接应用层软件,为区块链提供了业务驱动的接口。

3、

动态剖析——Fabric运行架构

在Fabric“静态”架构中,基于“功能”,实现了松耦合的总体架构。在业务执行的过程中,Fabric还站在“过程”的角度,对“过程”实现了进一步解耦。下面就让我们通过对这一过程的解析,来进一步了解Fabric是如何实现区块链去中心化特性。

3.1. 去中心化系统的分析

为了便于理解,在“运行”Fabric之前,让我们关注一下中心化系统和去中心化系统对一次业务请求的处理逻辑有何本质区别。

中心化系统:由于所有数据的中心化管理,系统仅需对针对业务请求提供“数据校验”“结果记录”的简单逻辑即可。

去中心化系统:数据分布在网络中的所有节点中,业务是由某一节点发起,对请求的处理如果同样中心化系统的简单逻辑,会形成单一节点数据差异化,显然不符合区块链“共同维护一套账本”的初衷。那么,我们就不能仅着眼与这一节点,应该关注整个网络,提供业务处理的也不仅仅是单一节点,而是整个网络所有节点。所以,针对业务请求的处理逻辑应该为发起节点“业务校验”之后,不能马上“记录结果”,而应该“执行结果广播”给所有节点,然后所有节点“结果记录”,这样才能确保整个区块链网络的账本一致性。并且,由于数据是由某一节点提交,其他节点同步,这就涉及到传播过程中的数据防篡改的安全机制,以及数据本身的可信度(可追溯)问题。

那么,去中心化需要解决的问题:

1)是所有网络节点执行交易如何让结果达成一致性的共识问题。

2)数据本身的防篡改、可追溯的防抵赖问题。

我们接下来让Fabric网络“动”起来,看看它是如何执行业务并解决这些问题的。

3.2. Fabric交易执行过程

Fabric将每一次访问区块链的业务请求,都视为一笔“交易”,根据交易在网络中执行的不同过程,将区块链的节点,区分为App/SDK、Peer、Order、CA,让不同类型的节点可以处理不同类型的工作负载。

1)CA节点:作为区块链网络的安全体系基石,为区块链的节点发行身份证。基于PKI体系和国际通用X.509标准,发行整个区块链网络中使用的证书与私钥,并提供可插拔式的证书管理机制。

2)App/SDK节点:连接区块链网络和业务应用软件的桥梁。本身也可以融入到业务应用软件中,即发起交易的客户端,通过SDK访问区块链网络资源。交易请求的发起者。

3)Peer节点:组成区块链网络的基本节点,参与组件区块链网络的各家机构都有自己的Peer节点,账本在此节点上保存,链码在此节点上运行。在逻辑上,是请求处理的起始点(“业务校验”),也是请求处理的终止点“结果记录”,根据处理的过程,可进一步拆分为Endorser(背书)节点和Committer(提交)节点。这看起来很像我们熟知的“数据库”,有存储过程(链码)执行,有结果记录(账本)。

4)Order节点:承担着区块链网络交易处理逻辑的“执行结果广播”过程。由于交易是在整个区块链网络的各Peer节点上发生,根据“共同维护一套账本”的初衷,Order需要集中式的对所有未记录交易实施时间上的排序,并将排序结果生成统一区块,广播给整个网络中的所有Peer节点,确保数据的有序、一致。

一个典型的交易处理过程如下所示:

0)证书签发:区块链网络中的某一机构的App/SDK节点在执行处理前,需要通过CA来发行该节点的身份证书。本处理仅执行一次,在之后的所有请求中,均使用本次签发的证书来执行交易请求。

1)发送交易请求:App/SDK节点通过Fabric SDK对交易内容实施Hash化,使用CA签发的密钥,对Hash化结果实施加密(签名),将交易内容与签名结果打包成交易请求,并根据交易执行的背书策略,将请求发送给一个或多个支撑交易的Peer(Endorser)。

2)“业务校验”:所有指定Peer(Endorser)接收请求后,执行签名校验来验证消息的正确性(未被篡改),然后启动指定的链码,访问本地的账本来模拟执行交易,生成读写集,其中读集合中包含账本数据的版本信息,并利用Peer的私钥针对读写集实施背书签名,将读写集与背书签名打包为背书结果返回App/SDK。注意,这里并不直接写入账本。

3)执行结果收集:App/SDK收集到背书结果后,校验结果是否一致,并将其转发给Order。

4)“执行结果广播”:Order收集到各方传输的交易结果后,按接收时间顺序排序,保证所有节点传输来的交易能按顺序执行,并生成区块,将区块再广播给网络中的Peer(Committer)节点。

5)“结果记录”:Committer节点从Order节点获取排序后的批量交易区块,对这些交易进行落盘前的最终检查(包括交易消息结构、签名完整性、是否重复、读写集合版本是否匹配等)。检查通过后执行合法的交易,将结果写入账本。

3.3. 痛点解读:如何达成共识

“共识”一词来源于分布式系统领域。也就是解决多个分布式节点的数据一致性的算法机制。具体来看,Fabric中的共识机制包括背书、排序和验证三个阶段,分别从三个维度,一步一步确保数据的一致性。

3.3.1. 背书

在去中心的系统中,所有组织机构彼此对等,没所谓的绝对“权威”,所有的业务实施均需要取得关联方的彼此“信任”,链码(智能合约)执行的背书过程,即视为针对一笔交易建立“信任”的过程。

交易处理过程2)“业务校验”中,所有收到请求的Peer节点,都启动链码,根据本地账本模拟执行交易,并对结果集实施签名,从各Peer自节点自身数据状态的角度,“承认”了这一交易的有效性。产生背书结果的过程,也即相当于业务参与群体从业务逻辑产生的数据状态变化这一维度上达成了共识。

比如A要向B转账100万,A的账户中现在有100万,A、B执行链码可以通过,同时C作为监管机构发现A有违约行为,需要罚没100万,那么C、A执行链码也可以通过,那么就代表A和B都承认了“可以转账100万”这一结果,C、A都承认了“可以罚没100万”这一结果,但是事实上这一结果能否实现,仍然要参考后续的共识步骤。

3.3.2. 排序

交易是在不同的节点同时发生的,这就导致分布式账本中,同一数据状态在不同的节点可能发生不同的交易情况,导致产生的结果集并不一样。这就涉及到交易执行的顺序。如果靠Peer节点之间互相通信来实现这一机制,那么就产生多次的1对n的节点广播以及各自节点内的复杂判断。为了避免这一问题,Fabric独立出Order节点,专职对交易结果执行排序。

在交易处理过程4)“执行结果广播”中,有独立的Order节点接收背书结果,按时间顺序排序后,广播给所有的Peer节点,也即相当于业务参与群体从业务发生顺序这一维度上达成了共识。

比如上一节的例子中,如何界定罚没资金的交易和转账交易的时间先后顺序,仅通过ABC三个节点间的通信来实现,会使问题复杂化,通过Order节点来界定,仅需收集执行结果,排序后再广播给ABC三点,凭借执行结果的数据版本,在后续的共识步骤中即可确定交易的成功失败。

3.3.3. 验证

交易处理过程5)“结果记录”中,包括检查交易结构自身完整性,交易所带背书签名是否满足预设的背书策略,并且交易的读写集是否满足多版本并发控制的相关要求。验证通过后将新区块加入到区块链中并且更新账本信息。也即相当于从业务参与群体从交易最终结果这一维度上达成了共识。

比如上一节的例子中,如果罚没资金的排序优先,那么这一区块会成功写入区块链中记录,并更新了数据版本,后续的转账交易,由于读写集版本判断发现已经不满足版本要求,那么这一笔交易会被标记为无效。

3.4. 痛点解读:如何防抵赖

在分布式的区块链网络中,没有权威性的中心化系统对数据真实性实施担保,数据来源于区块链网络中的所有节点,这就要求区块链网络具备数据防抵赖的机制,用以确保去中心化系统各机构间的信任。Fabric从传输过程和数据存储两个维度建立了防抵赖机制。

3.4.1. 传输过程

参考交易处理过程中,如1)发送交易请求,数据在分布式系统的节点间传播之前,均在本节点对数据进行一次摘要处理(Hash),并使用节点私钥对摘要实施非对称加密(签名),之后将数据与签名打包成消息传输给目标节点。在目标节点处对传输数据再实施一次摘要处理(Hash),并用原始节点的公钥解密签名后,将解密结果与摘要对比,验证一致方认为消息内容没有被篡改。

原始节点传输的消息,其他节点没有原始节点的私钥,无法伪造原始节点的签名,如果第三方篡改数据内容,会导致目标节点数据摘要验证无法通过,交易无法执行;如果第三方篡改签名内容,会导致目标节点解密签名处理异常,交易无法执行。签名及验证机制确保了第三方无法对区块链的传输过程实施篡改。

3.4.2. 数据存储

每个Peer节点都保存有账本。账本记录发生在区块链网络中的所有交易信息。账本结构由3部分组成:

1)区块链结构:相当于传统数据库中记录交易流水的表。进行排序后的交易集合形成区块(block),交易通过读写集合进行表达,通过链式结构存储于文件系统中。

2)索引数据库(Block Index):相当于传统数据中对大数据表建立的索引,用于加速查询。实际存放各区块的索引信息。

3)状态数据库(State DataBase):这是Fabric的独创,相当于传统数据库的表,用键值对记录交易变更的最终结果。

在这三部分中,区块链结构即为Fabric对区块链核心概念(顺序存储的链式结构)的具体实现,也即是数据存储防篡改、可追溯的具体体现。

如下左图所示,原始未篡改的正常区块链的区块结构由一个按产生时间顺序相连的区块(Block)构成,每个Block都存有上一个区块的Hash,并存有本区块的Hash。每个区包含若干事务,区块Hash即为这若干事务内容的Hash。每个事务又包含交易的未加密信息以及经交易创建者私钥签名的交易内容Hash。

如下右图所以,若想在本地节点篡改某一交易内容,那么根据存储的原理,首先需要伪造交易创建者的签名,姑且不论能否获得交易创建者的私钥,在签名伪造成功后,仍需持续更改本区块的hash值,这就会直接导致后续区块无法通过Hash值连接本区块,也就需要对后续区块的所有Hash值进行再计算,再更改。即使进行了如此大量的运算与更改,但也仅仅局限于本地节点的账本中区块链结构,仍需继续更改索引数据库和状态数据库。假设这些更改在本地都可以正确实施,但是,区块链是一个分布式的网络系统,单一节点的更改,必须得到其他足够多节点的认可并同步数据,这才能使后续业务正确实施。所以,从整个篡改过程的层层深入,难度逐渐加大至不可实施。

这就在数据存储上确保了防抵赖。

4、

总结

区块链技术Fabric1.0可以说充分体现了区块链的核心理念,并解决了去中心化系统的痛点,确保了Fabric 搭建的网络,具有去中心、数据公开透明、不可篡改、可追溯的区块链显著特性。并且,从设计之初,充分做到了功能模块解耦,运行过程节点解耦,便于升级扩展。其账本的状态数据库和区块链结构的配套使用,简洁的SDK组件,成熟的权限管理策略,为开发者提供了极大便利,降低了开发难度。

所谓,好钢用在刀刃上,再好的利器没有用武之地,也无法体现它的价值。虽然从实现区块链的概念上可以将Fabric解读为分布式账本,但我们不能仅仅将其局限为相当于数据库记录功能。无论是静态模块架构,还是动态运行原理,Fabric都试图将 “区块链是建立无中心系统结构的组织信任桥梁”这一信息传达给我们。在应用过程中, “建立信任”“建立互通渠道”,才是系统建设的真正立足之处。比如机构间通过建立区块链网络,将机构间的业务协议编写为链码,简化机构间的协作流程。

在进一步利用Fabric研究实践区块链技术的同时,我们也发现了一个问题。区块链分布式账本思想,带来了数据公开透明的共享,这一特性在所有信息均可公开的业务场景下得到了淋漓尽致的发挥。但是,如果网络中的节点并不应该对等的分享所有信息,比如在我们期货行业的背景下,对资金和仓单实施管理,那么参与者之间就不能无差别分享彼此的信息,这就要求在统一账本的管理下,能够分角色对数据实施隐私保护,能够有差别的访问数据资源。

个人认为,遗憾的是,Fabric本身对数据隐私的实现并不完美。Fabric本身提供了 “通道”(channel)机制,在区块链网络中建立逻辑上的账本和交易的隔离环境。在区块链网络创建之初定义通道,定义Peer和Order节点加入哪些通道,加入到不同通道的Peer节点能够维护各个通道对应的账本状态,即使是同一个Peer和Order,加入了不同的通道,那么各通道下的账本和交易也是完全隔离的。通道将参与者的数据(包含链码)进行隔离,满足了不同业务场景下的“不同的人访问不同数据”的基本要求。但是,无法动态创建通道并动态组建通道内的节点,通道间账本无法共享也使隔离后的数据失去了彼此之间的关联性与灵活性,将通道的概念局限为了“子链”的范围,没有根本解决数据隐私问题。如果需要更进一步限制数据隐私,需要开发者按照业务需求与设计,针对数据实施加密或HASH化等处理。

Fabric作为区块链技术的具体实现,仍然在不断完善和升级,作为该技术的粉丝,衷心期待它走向更加强大、更加成熟,我们也将持续跟踪。怀抱“终身学习”的态度,我们仍然走在路上。

END

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180226G0TMXJ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券