跳到主要内容

超级账本Fabric

Linux基金会于2015年12月启动了名为“超级账本”(Hyperledger)的开源项目,旨在推动各方协作,共同打造基于区块链的企业级分布式账本底层技术,用于构建支撑业务的行业应用和平台。超级账本将提供多种的区块链技术框架和代码,包含开放的协议和标准,不同的共识算法和存储模型,以及身份认证、访问控制和智能合约等服务。模块化、性能和可靠性是很重要的设计目标,用于支持各种各样的商业应用场景。

从创始成员看,参与超级账本项目的公司阵容相当强大,不仅有IBM、Intel、思科等科技巨头,还有摩根大通、富国银行、荷兰银行等金融大鳄,还有R3,ConsenSys等专注区块链的公司。截至2016年6月底,超级账本项目已经汇集了全球超过80家公司,声势之浩大是其他技术联盟或开源项目无法比拟的。不管是从代码数量还是从社区参与度来看,超级账本都是最大的区块链开源项目。和比特币、以太坊等由极客主导的公有链项目相比,超级账本则是由大企业领衔的商业化联盟链项目。

Fabric(编织品)项目的目标是实现一个通用的许可链的底层基础框架。为了适用于不同的场合,Fabric采用模块化架构提供可切换和可扩展的组件,包括共识算法、加密安全、数字资产、记录仓库、智能合约和身份鉴权等服务。Fabric克服了比特币等公有链项目的缺陷,如吞吐量低、交易公开无隐私性、无最终确定性以及共识算法低效等问题,使得用户能够方便地开发商业应用。

区块链的存储主要包含以文件形式存储的链式区块数据,以及在数据库保存的键值对(Key-Value Pair)状态数据。其中链式区块数据存放的是交易的原始数据区块,通过区块的哈希值形成防篡改的链式结构。状态数据库的作用主要是加速对数据的访问。因为区块链数据采用链式顺序存放,在读取数据时通常需要遍历整个链的数据块,采用数据库能够从索引迅速定位到所需数据。 Fabric中的智能合约称为“链码”(chain code)。链码部署在节点上,采用容器技术形成隔离的运行环境。链码的生命周期管理主要包括链码的安装、实例化、调用和终止等。 作为联盟链方案,Fabric包含管理成员身份的功能。参与区块链网络的成员身份必须是明确的,成员之间知道彼此组织身份信息,每个交易都有确定的参与方和背书方,这是绝大多数商用系统的需求。相比之下,许多公有链的用户身份是匿名的,参与方无须确认身份信息。 服务层利用核心层的基础功能,封装成服务的形式,提供给应用端来使用。账本服务和交易服务通过核心层的共识算法和区块链存储,实现基本的区块链数据操作能力。-链码服务提供智能合约的功能封装。事件服务则提供应用侦听系统事件并处理的功能。权限服务根据成员和用户的身份信息,对其操作权限进行控制,成为商业应用中安全管理的一部分。 接口层的目的是使Fabric的应用(客户端)能够方便地调用区块链的服务。接口主要以API的形式提供,能够完成通道、链码、交易等方面的操作。为了便于编程语言的调用,Fabric提供了绑定不同语言的SDK,如Node和Java等的SDK。此外,Fabric还提供了命令行接口CLI,可无须编程,通过命令直接调用Fabric的功能。

主要组件 Fabric的组件包括客户端(Client)、网络节点(Peer)、CA(Certificate Authority)节点和排序节点(Orderer)。 客户端的主要作用是和Fabric系统交互,实现对区块链系统的操作。这些操作分为管理类和链码类。管理类操作包括启停节点和配置网络等;链码类操作主要是链码的生命周期管理,如安装、实例化以及调用链码。最常用的客户端是命令行客户端(CLI),此外是用Fabric SDK开发的应用客户端。用户可以通过不同的客户端使用Fabric系统的功能。 网络节点(Peer)是区块链去中心化网络中的对等节点,按照功能主要分为背书节点(Endorser)和确认节点(Committer)。背书节点主要对交易预案进行校验、模拟执行和背书。确认节点主要负责检验交易的合法性,并更新和维护区块链数据与账本状态。在实际部署中,背书节点和确认节点既可以部署在同一物理节点上,也可以分开部署。 排序节点(Orderer)的主要职责是对各个节点发来的交易进行排序。在并发的情况下,各个节点交易的先后时序需要通过排序节点来确定并达成共识。排序节点按照一定规则确定交易顺序之后,发给各个节点把交易持久化到区块链的账本中。排序节点支持互相隔离的多个通道,使得交易只发送给相关的节点(Peer)。 CA节点主要给Fabric网络中的成员提供基于数字证书的身份信息,可以生成或取消成员的身份证书(certificate)。在成员身份明确的基础上,Fabric可以实现权限控制的管理。 Fabric网络的组件往往归属于不同的组织,在组织之间形成对等的去中心化网络。每个组织通常拥有自己的客户端、网络节点和CA节点,并且可以根据需要创建一个或多个不同的类型节点。排序节点不属于某个组织的实体,属于组织共同维护的组件。各个组件的相互关系如图9-2所示。

P2P网络 Fabric的节点组成了一个P2P的网络。P2P网络的节点可以通过直接交换来共享资源和服务。节点彼此之间处于对等的地位,并不依赖于集中的服务节点来进行资源调度。网络中的每一个节点既能充当网络服务的请求者,又能响应其他节点的请求,提供网络资源和服务,以达到资源共享的目的。 在Fabric中,P2P技术主要用于网络节点之间的健康检测和账本同步。节点间的P2P网络由Gossip协议实现,在通道中的各个节点会持续广播和接收Gossip消息。Gossip的内容包含节点的状态、账本数据以及通道数据等信息,由于Gossip消息需要发送者的签名,因此伪造的消息很容易被识别。此外,还可以基于消息的签名对信息进行隔离。通过Gossip协议,受延迟、网络分区或其他因素而导致账本没有同步的节点,最终都会同步到最新的账本状态。

通道 商业应用的一个重要需求是私密性交易,为此Fabric设计了通道(Channel)来提供成员之间的隐私保护。通道是部分网络成员之间拥有独立的通信渠道,在通道中发送的交易只有属于通道的成员才可见,因此通道可以看作是Fabric的网络中部分成员的私有通信“子网”。 通道由排序服务管理。在创建通道的时候,需要定义它的成员、组织、锚节点(anchor peer)和排序服务的节点。一条和通道对应的区块链结构也同时生成,用于记录账本的交易。通道的初始配置信息记录在区块链的创世块(第一个区块)中。通道的配置信息可以用增加一个新的配置区块来更改。 每个组织可有多个节点加入同一个通道。这些节点中可以指定一个锚节点(或多个锚节点做备份)。锚节点代表本组织与其他组织的节点交互,从而发现通道中的所有节点。另外,同一组织的节点会选举或指定主导节点(leading peer)。主导节点负责接收从排序服务发来的区块,然后转发给本组织的其他节点。主导节点可以通过特定的算法选出,因此保证了在节点数量不断变动的情况下仍能维持整个网络的稳定性。 在Fabric的网络中,可能同时存在多个彼此隔离的通道,每个通道包含一条私有的区块链和一个私有账本,通道中可以实例化一个或多个链码,以操作区块链上的数据。由此可见,Fabric是以通道为基础的多链多账本系统。

分布式账本 Fabric里的数据以分布式账本的形式存储。账本由一系列有顺序和防篡改的记录组成,记录包含着数据的全部状态改变。账本中的数据项以键值对的形式存放,账本中所有的键值对构成了账本的状态,也称为“世界状态”(World State)。每个通道中有唯一的账本,由通道中所有成员共同维护。每个确认节点上都保存了它所属通道的账本的一个副本,因而是分布式账本。对账本的访问需要通过链码实现对账本键值对的增加、删除、更新和查询等操作。 账本由区块链和状态数据库2部分组成。 区块链是一组不可更改的、有序的区块(数据块),记录着全部交易的日志。每个区块中包含若干个交易的数据,不同区块包含的交易数量可以不同。区块之间用哈希链(Hashed-link)关联:每个区块头包含该区块所有交易的哈希值,以及上一个区块头的哈希值。这样的链式架构可以确保每个区块的数据不可更改,以及每个区块之间的顺序关系不可更改。这个特点决定了区块链的区块只可以添加在链的尾部。 状态数据库记录了账本中所有键值对的当前值,相当于对当前账本的交易日志做了索引。链码执行交易的时候需要读取账本的当前状态,从状态数据库可以迅速获取键值的最新状态。如果没有状态数据库,要获得某个键值时,需要遍历整个区块链中和该键值相关的交易,效率非常低。因此,读取状态数据库可以认为是快速定位和访问某个键值的方法。另外,当状态数据库出现故障的时候,可以通过遍历账本重新生成。当一个区块附加到区块链尾部的时候,如果区块中的有效交易修改了键值对,则会在状态数据库中做相应的更新,这样区块链和状态数据库就能始终保持一致。 区块链的数据块以文件形式保存在各个节点中。状态数据库原理上可以是各种键值数据库,Fabric缺省使用的是LevelDB,它也支持CouchDB的选项。CouchDB除了支持键值数据之外,也支持JSON格式的文档模型,能够做复杂的查询。

共识机制 Fabric的网络节点本质上是互相复制的状态机,节点之间需要保持相同的账本状态。为了实现这个目的,各个节点需要通过共识(consensus)过程,对账本状态的变化达成一致性的认同。因为账本记录的是系统中发生的交易,共识机制实际上就是要确保各个节点看到相同的交易顺序和交易内容,从而保证各个节点都处于相同的状态。 Fabric的共识过程包括3个阶段:背书、排序和校验。 1.背书 在背书(endorsement)阶段,背书节点对客户端发来的交易预案进行合法性检验,然后模拟执行链码得到交易结果,最后根据设定的背书逻辑判断是否支持该交易预案。如果背书逻辑决定支持交易预案,它将把预案签名后发回给客户端。缺省情况下,背书节点的背书逻辑是直接支持预案并签名。但是节点也可以依照业务规则设定背书逻辑,从而仅对符合业务需求的交易进行背书。如果背书节点判定不支持交易,则给客户端返回错误信息。 客户端通常需要根据链码的背书策略,向一个或者多个成员的背书节点发出背书请求。背书策略会定义需要哪些节点背书交易才有效,例如需要5个成员的背书节点中至少3个同意,或者某个特殊身份的成员支持等。客户端只有在收集满足背书策略的支持之后,广播出去的交易才能被视为有效。 2.排序 排序(ordering)阶段就是由排序服务对交易进行排序,确定交易之间的时序关系。排序服务把一段时间内收到的交易进行排序,然后把排序后的交易打包成区块,再把区块广播给通道中的成员。采用这种方式,各个成员收到的是一组发生顺序相同的交易,从而保证了所有节点数据的一致性。 Fabric 1.0中的排序服务支持可插拔的架构。除了提供的SOLO和Kafka模式外,用户还可以添加第三方的排序服务。SOLO是单机确认模式,仅适合开发测试中使用。Kafka模式是基于Kafka开源的分布式数据流平台,具有高扩展性和容错能力,适合用在生产系统。需要注意的是,Kafka只提供了CFT类型的容错能力,即仅可对节点的一般故障失效容错,缺乏对节点故意作恶行为进行容错的能力。因此,需要第三方的容错方案来支持BFT。 排序服务是共识机制中重要的一环,所有交易都要通过排序服务的排序才可以达成全网共识,因此排序服务要避免成为网络上的性能瓶颈。为此,排序服务采用轻量级设计,只完成确定交易顺序的功能,不参与其他操作。 3.校验 校验(validation)阶段是确认节点对排序后的交易进行一系列的检验,包括交易数据的完整性检查、是否重复交易、背书签名是否符合背书策略的要求、交易的读写集是否符合多版本并发控制MVCC(Multiversion Concurrency Control)的校验等。当交易通过了所有校验之后,将被标注为合法并写入账本中。因为所有的确认节点都按照相同的顺序检验交易,并且把合法的交易依次写入账本中,所以它们的状态能够始终保持一致。 更多的共识机制的介绍参见9.1.9节。

智能合约(链码) “智能合约”的概念最早出现在1996年,由密码学家尼克·萨博(Nick Szabo)首次提出。他对智能合约的定义为:“智能合约是一套以数字形式定义的承诺(promises),包括合约参与方可以在上面执行这些承诺的协议。” 智能合约能够部署和运行在区块链环境中,由一段代码来描述相关的业务逻辑。部署后的智能合约在区块链中无法修改。智能合约的执行完全由代码决定,不受人为因素的干扰。一般来说,参与方通过智能合约规定各自的权利和义务、触发合约的条件以及结果,一旦该智能合约在区块链环境中运行就可以得出客观、准确的结果。 在Fabric中,智能合约也称链码(chaincode),分为用户链码和系统链码2种,通常所说的链码指的是用户链码。链码是访问账本的基本方法,一般是用Go等高级语言编写的、实现规定接口的代码。上层应用可以通过调用链码来初始化和管理账本的状态。只要有适当的权限,链码之间也可以互相调用。 链码安装在背书节点上,需要在某个通道上实例化并且定义相应背书策略后才能运行。链码部署后不可更改,但是可以通过升级来发布新的功能或修复问题。在Fabric的设计中,链码运行在一个安全的Docker容器沙盒内。该容器由背书节点创建和管理,以便隔离背书节点和链码的运行环境。

成员服务提供者 Fabric与其他公有链系统的重要区别在于,Fabric具有成员身份和权限管理的能力。成员服务提供者MSP(Membership Service Provider)抽象地描述了参与者在网络中的身份,成员服务是成员服务提供者的具体实现。参与者在网络中的身份由参与者的成员服务描述,成员服务最重要的一个部件是参与者所持有的身份证书。该证书由特定CA签发,当若干参与者的身份证书可追溯到同一个根CA时,则认为这些参与者处于同一个信任链中,这些参与者也称该信任链的成员(member),这些成员可用组织(organization)来代表。组织中的成员可以分为普通成员和管理员2种角色,管理员角色拥有对组织配置进行修改的权限。 在实际运行中,参与者通过成员服务可对其他参与者进行身份认证、授权访问权限等操作以管理区块链网络,从而对账本数据的访问控制可以在更广泛的网络和通道层面上进行操控,有助于实现数据的授权访问和隐私保护。例如:可以允许特定参与者调用链码应用程序,但阻止他们部署新的链码;制定规则以拒绝验证由某些参与者签名的交易等。

交易流程 1)应用端首先构建交易的预案,预案的作用是调用通道中的链码来读取或者写入账本的数据。应用端使用Fabric的SDK打包交易预案,并使用用户的私钥对预案进行签名。应用打包完交易预案后,接着把预案提交给通道中的背书节点。通道的背书策略定义了哪些节点背书后交易才能有效。应用端根据背书策略选择相应的背书节点,并向它们提交交易预案。 2)背书节点收到交易预案后,首先校验交易的签名是否合法,然后根据签名者的身份,确认其是否具有权限进行相关交易。此外,背书节点还需要检查交易预案的格式是否正确以及之前是否提交过(防止重放攻击)。在所有合法性校验通过后,背书节点按照交易预案调用链码。链码执行时,读取的数据(键值对)是节点中本地的状态数据库。需要指出的是,链码在背书节点中是模拟执行,即对数据库的写操作并不会对账本造成改变,所有的写操作将归总到一个写入的集合(Write Set)中记录下来。如果在链码中对某个数据项写完之后再读取,得到的数据是在链码执行前的旧值,因为新值并没有实际写入账本中。在链码执行完成后,将返回链码读取过的数据集(Read Set)和链码写入的数据集(Write Set)。读集和写集将在确认节点中用于确定交易是否最终写入账本。 3)背书节点把链码模拟执行后得到的读写集(Read-Write Set)等信息签名后发回给预案提交方(应用端)。 4)应用端在收到背书响应之后,检查背书节点的签名和比较不同节点背书的结果是否一致。如果预案是查询账本的请求,则应用端无须提交交易给排序节点。如果是更新账本的请求,应用端在收集到满足背书策略的背书响应数量之后(例如,背书策略规定的至少5个背书节点中的4个背书响应),把背书预案中得到的读写集、所有背书节点的签名和通道号发给排序节点。 5)排序节点在收到各个节点发来的交易后,并不检查交易的全部内容,而是按照交易中的通道号对交易进行分类排序,然后把相同通道的交易打包成数据块(blob)。 6)排序节点把打包好的数据块广播给通道中的所有成员。数据块的广播有2种触发条件:一种是当通道的交易数量达到某个预设的阈值;另一种是在交易数量没有超过阈值但距离上次广播的时间超过某个特定阈值时,也可触发广播数据块。两种方式相结合,使得排序过的交易可以及时广播出去。 7)确认节点收到排序节点发来的交易数据块后,逐笔检查区块中的交易。先检查交易的合法性以及该交易是否曾经出现过。然后调用VSCC(Validation System Chaincode)的系统链码检验交易的背书签名是否合法,以及背书的数量是否满足背书策略的要求。接下来进行多版本并发控制MVCC的检查,即校验交易的读集(Read Set)是否和当前账本中的版本一致(即没有变化)。如果没有改变,说明交易写集(Write Set)中对数据的修改有效,把该交易标注为有效,将交易的写集更新到状态数据库中。如果当前账本的数据和读集版本不一致,则该交易被标注为无效,不更新状态数据库。数据块中的交易数据在标注成“有效”或“无效”后封装成区块(block)写入账本的区块链中。 上述的交易流程中,Fabric分离了背书节点和确认节点的职责,增加了系统的吞吐量,使系统更具可扩展性。在交易的确认过程中,采用了MVCC的乐观锁(optimistic locking)模型,提高了系统的并发能力。

应用场景 超级账本有个重要的设计原则是按照“用例驱动”(use case driven)的方式来实现的,所有功能都应该有对应的用例需求。鉴于超级账本是个通用型框架,无法预先确定将来所有的应用场景,因此,定义出部分典型的用例,可使超级账本先满足这部分代表性的区块链应用需求,然后再用可替换模块来满足其他需求。目前,Fabric项目主要针对下面几种用例:金融资产管存、公司行为、供应链、主数据管理以及分享经济。需要指出的是,这些用例并非一成不变,随着项目的推进,可能会有所调整和增减。 (1)金融资产管存 金融行业最关心的区块链应用估计是资产的分布式管存,因为把资产(如证券)数据存放在区块链网络后,资产的利益相关人可以直接访问资产数据,而无需经过传统的中间人,可大幅度提高效率和节约成本。资产的交易可准实时地完成,交易的人员也能近乎实时地查询到相关资产信息。资产利益人可赋予资产自动执行的业务规则,从而进一步降低运营成本。与公有区块链应用的较大区别是,金融资产及其相关的交易、业务规则通常是保密的,例如,资产的余额只有持有人才能知道,其他人无法查看。 (2)公司行为 公司行为通常是上市公司发起的有关公司证券的事件,一般和股东有关,有时需要股东做适时的回应,例如要约收购、分红扩股、收购合并等。不管有多少中间机构在处理的流程当中,公司需要及时地把事件的完整信息递交给所有股东。当股东作出某项决定后,该结果会实时处理或清算(如发行新股等)。在整个事件处理过程中,应该保护股东的隐私,以确保投资者所作决定不受外界因素的左右。 (3)供应链 在供应链中,所有的参与者都通过区块链记录、追踪和共享各种数据,例如原材料来源、零部件检测结果以及货物的出处等。这些数据记录在区块链里,并贯穿于货物的生产、运输和销售等环节,从而提供深度回溯查询等核心功能。 (4)主数据管理 在很多的行业里,不同的组织之间往往共享一些主数据(Master Data)。例如,不同的移动运营商之间,需要共同维护一份发射机站地理位置的数据。虽然主数据不是交易类型的商业信息,但是作为各组织间唯一的全局性数据,采用分布式的区块链来保证数据的质量和完整性具有非常重要的意义。 (5)分享经济 分享经济是指将闲置或没有被充分利用的实物资源分享出来,有偿地供陌生人暂时使用的一种商业模式。这种崭新的模式已经延伸到日常生活的多个领域,包括交通、住宿、保健、零售、教育等行业。在分享经济的模式下,最需要解决的就是陌生人之间的信任问题,即资源的提供方和资源的租用者,如何在缺乏信任的基础上安全地完成交易。目前主要的手段是通过分享经济平台来确保信任度。分布式区块链将是全新的一种去信任的方式,它不使用任何中间平台,便可达到各方参与者可靠交易的目的。

部署方式 Fabric的网络由几类节点组成:身份服务节点、验证节点(validating node)、非验证节点(Non-validating node)和若干个应用节点,如图8-2所示。 ·身份服务节点:负责发放和管理用户及组织的身份,具体来说就是在注册、交易、传输过程中使用的各类数字证书,以及区块链相关的密钥。 ·验证节点:创建和校验交易,并且维护智能合约的状态。在执行交易时,一般需要和其他多数的验证节点达成共识(取决于共识算法),然后才能更新本地的账本数据。每个验证节点在本地都保存一份账本的副本。 ·非验证节点:主要是接收客户端的请求,组装交易,并发往验证节点处理,从这个角度看,非验证节点像交易预处理器,并不负责交易的实际执行。为了加速客户端的查询响应速度,非验证节点在本地也保留一份账本数据的拷贝。 ·应用节点:主要提供用户端(例如浏览器或移动设备)的后台服务,在收到请求后,把交易请求直接发往(或经由非验证节点转发)验证节点处理。

Fabric的部署方式按照实际需要可有多种形式。由于Fabric是联盟链,组成网络的节点分别属于不同的联盟成员,只要这些节点可通过网络互相连接,每个成员能够选择自己节点的部署方式:既可把节点部署在自有的数据中心,也可把节点部署到公有云中。如果在云端部署节点,需要更强的加密手段来防止公网潜在的恶意攻击。由于Fabric节点部署的多样性,规划的时候应该把通信延迟、网络故障、节点失效、网络恢复等因素综合考虑在内,以符合应用的要求。