链原——Fabric
超级账本Fabric
系统架构
引入了部分中心化服务节点。
为了满足联盟链跨组织多业务协同的需求,超级账本Fabric区块链系统提供了多通道机制,可以同时建立多个逻辑上独立、相互隔离的区块链,每个通道对应唯一的区块链与账本
提供了链码(Chaincode)机制,实现比以太坊智能合约更灵活、强大的智能合约功能,每个节点都可以部署运行链码,链码将存储于区块链中,加载到每个Peer节点上的轻量化Docker容器中执行。
【1】
系统逻辑架构
【2】
超级账本Fabric系统不提供加密数字货币功能,因此没有激励层
系统系统的存储层主要采用文件系统、LevelDB或可选的CouchDB Key-Value数据库,为超级账本Fabric系统相关的区块链、分布式账本、智能合约、X.509数字证书、日志、配置文件等数据提供高效、可靠持久化存储服务。
系统的数据层是系统核心功能层级之一,对超级账本Fabric系统核心的区块、区块链、交易、账本、地址、世界状态等关键数据结构进行定义和处理,负责将交易打包进区块,由区块组成区块链,并构建了世界状态、区块索引、键历史索引等数据结构,并基于底层的存储服务提供对超级账本Fabric区块链数据的安全读写访问管理。
系统的网络层是系统核心功能层级之一,主要采用非结构化P2P网络,基于Gossip P2P网络协议,实现网络节点快速发现与连接,以及区块、交易数据的分发与同步,为超级账本Fabric系统各网络节点之间提供节点发现与安全连接通信机制,为交易、区块信息在区块链网络所有节点之间提供高效传播与有效性验证机制。
系统的共识层是系统核心功能层级之一,由于超级账本Fabric系统不提供加密货币发行和激励机制,因此共识层不需要采用类似比特币、以太坊等系统的PoW竞争计算共识机制,系统默认提供Solo/Kafka等多种可选的共识排序服务,并提供对共识机制进行扩展的接口,允许自定义扩展共识服务插件。
系统的合约层采用链码(Chaincode)实现智能合约功能,链码支持Go、Java、Node.js等多种开发技术实现,提供了比以太坊系统更丰富的链码开发API接口,可在链码中实现对区块链和账本更复杂的业务操作逻辑,同时采用更轻量和开发的Docker容器技术实现链码的安全、高效运行。
系统的接口层提供了基于JSON RPC、Web3.js的SDK接口和命令行接口。
系统的应用层基于接口层提供的灵活多样的SDK接口,可以实现面向各种应用场景和业务逻辑的企业级联盟链或私有链应用。
数据层
在超级账本Fabric系统中,第一个创世区块不包含任何交易数据,从第二个区块开始,每个区块由区块头(Block Header)、区块数据(Block Data)、区块元数据(Block Metadata)等部分组成,将所有不可改变的、有序的交易记录存放在区块数据中,每个区块由区块数据的哈希值唯一标识,每个区块都保存了前一个区块的区块哈希值,所有区块链接在一起构成区块链。
每个区块的区块头包含区块编号(BlockNumber)、当前区块的哈希(CurrentBlockHash)、父区块的哈希(PreviousBlockHash)等3个字段,如图所示。
【3】
【4】
每个区块的区块数据域包含记录到该区块中的多条交易数据,如图所示。区块数据域中所有交易数据的哈希计算结果将作为当前区块哈希保存到区块头中。每个区块的元数据域包含了区块的创建时间、区块创建节点的证书及公钥、区块创建节点的数字签名等信息。
【5】
账本数据
超级账本Fabric系统区块链每个通道都会拥有一个独立的分布式账本,每个账本由区块链(Blockchain)、状态数据库(State Database)、区块索引库(Block Index Database)、键历史索引库(Key History Index Database)等要素构成。其中,区块链和状态数据库是两个最重要的组成部分,如图所示。
【6】
状态数据库
状态数据库又称为“世界状态(World State)”,状态数据库实际上存储的是所有曾经在交易中出现的写操作相关的键值对的最新值。超级账本Fabric系统采用CouchDB或LevelDB数据库来构建状态数据库。
区块索引库
区块索引库提供了对区块进行快读定位查找的索引信息(区块存储文件位置指针),可以通过区块序号、区块哈希、交易ID、区块序号+交易序号等查询条件快速查找区块,类似于关系型数据库中的索引表。超级账本Fabric系统采用LevelDB数据库来构建区块索引库。
键历史索引库
键历史索引库记录引起区块链系统状态改变的键值对<key, value>数据的历史信息,可用于查询某个 key 的历史修改记录,但是并不存储key具体的值,而只记录在哪个区块的哪个交易里,对key的值进行了修改。超级账本Fabric系统采用LevelDB数据库来构建键历史索引库。
交易数据
在超级账本Fabric系统中,键历史索引库记录引起区块链系统状态改变的键值对<key, value>数据的历史信息,可用于查询某个 key 的历史修改记录,但是并不存储key具体的值,而只记录在哪个区块的哪个交易里,对key的值进行了修改。
(1) 交易头(Header)
交易头包含与交易相关的必不可少的元数据,包括交易ID、交易类型、交易发出时间、通道ID、链码名称及其版本等字段。
(2) 交易签名(Signature)
交易签名字段包含交易创建者客户端应用程序的公钥与数字签名,用于检查交易内容是否被篡改。
(3) 交易提案(Proposal)
交易提案字段是客户端应用程序发出的创建交易提案的参数编码后的结果,包含要调用的链码(超级账本的智能合约)的方法名称、调用方法所需的输入参数,链码根据交易提案的输入参数对区块链系统状态和账本数据进行更新。
(4) 交易响应(Response)
交易响应是链码被调用后返回给发起交易的客户端的输出结果,即区块链系统状态(世界状态)改变前、后的键值对<key, value>数据,具体分为读集合(ReadSet)与写集合值(WriteSet)。
(5) 背书列表(Endorsement)
背书列表包括达到背书策略规定的足够多的背书节点的公钥与数字签名,用于检查哪些组织对该交易进行背书,防止抵赖。
系统的账本数据包含两个最重要的组成部分——区块链和状态数据库。
状态数据库又称为“世界状态”。每个交易实质上都是通过调用智能合约(即链码),提交一系列与交易相关的键值对<key, value>数据的读、写(增、删、改)操作,可分为对键值对<key, value>数据的读集合和写集合,其中读操作不会改变区块链系统状态和账本数据,而写操作会改变区块链系统的状态和账本数据。
网络层
主要提供以下网络管理功能:
(1) 区块链P2P网络的组网与通道管理
(2) 各网络节点的节点发现、安全连接与通信管理
(3) 新区块或交易数据广播与验证管理
(4) 各网络节点之间区块链及账本数据同步管理
超级账本Fabric系统大部分网络结构属于非结构化P2P网络,但是保留了部分中心化功能节点(Orderer排序节点)。
节点
【7】
(1) Peer对等节点
超级账本Fabric系统的Peer节点是组建P2P网络的真正意义上的对等节点,Peer节点可以具有记账(Committer)、背书(Endorser)、主节点(Leader)、锚节点(Anchor)等不同的功能角色。其中每个Peer节点一定具有记账功能角色,即Peer节点都可以对区块链与账本进行写入操作,当Peer节点接收到Orderer节点的新区块广播时,会对区块数据进行校验后写入本地区块链和账本中。
在超级账本Fabric系统中,Peer节点默认的网络服务端口如下:
• Peer节点P2P连接服务端口7051
• Peer节点链码连接请求监听端口7052
• Peer节点事件服务监听端口7053
• Peer节点CouchDB数据库服务端口5984
(2)Orderer排序节点
超级账本Fabric系统的Orderer节点的主要功能是实现共识管理。Client客户端节点发起的所有交易,经过Peer节点背书后,将统一发送给Orderer节点。Orderer节点负责接收属于不同通道的交易请求,按通道对接收到交易进行排序,再将交易信息打包进新的区块中,然后将新区块信息广播给对应通道的Peer节点。Orderer节点默认的排序服务端口是7050。
(3) Client客户端节点
超级账本Fabric系统的Client客户端节点一般表示用户或基于区块链的应用系统,作为实际交易的发起者,必须连接到一个Peer节点,实现对区块链系统的访问互动。Client客户端节点可以向多个具有背书功能角色的Peer节点提交新的交易提案,当收集到Peer节点回复的足够的背书后,就可以向Orderer排序节点发送交易,等待交易被写入新区块中。
(4) CA证书服务节点
超级账本Fabric系统的CA节点是X.509数字证书颁发机构,CA节点接收Client客户端节点的注册申请,以便获取身份证书,在超级账本Fabric系统网络上所有的操作都需要使用证书验证用户的身份。
在超级账本Fabric系统中,CA节点默认的证书服务端口是7054。
多链与多通道
超级账本Fabric系统区块链引入了多通道(Channel)机制,每个通道对应一条逻辑链和一个分布式账本,区块链网络的每个节点可以属于一个或多个通道,因此超级账本Fabric系统支持多链。
超级账本Fabric系统主要用于构建联盟区块链,所谓联盟一般是由多个组织构成,网络中的Orderer节点、CA节点通常是由联盟链的发起与权威可信管理机构提供,网络中的Peer节点、Client客户端节点由联盟中的不同组织提供。如果联盟中包含一个组织,则构建的区块链就可以视为私有链。
超级账本Fabric系统一个通道对应一条链和一个账本,一个通道中可以包含不同组织的多个Peer节点,每个组织的多个Peer节点中至少有一个主节点和锚节点。
主节点:
主要用于在通道内接收Orderer节点的区块广播,并将验证后的区块通过Gossip协议传播给通道内所属组织的其它Peer节点进行记账。
锚节点:
主要用于在组织内及通道内跨组织的节点发现,一个组织在通道内的Peer节点可以通过其他组织的锚节点发现其他组织在该通道内的所有Peer节点。
节点发现管理
【这里有图片但是没有截屏】
- 在超级账本Fabric系统的P2P网络中,任何Peer节点都属于某个组织,一个组织至少包含两个以上的Peer节点,不存在无组织的Peer节点。同一组织的Peer节点之间,可以相互作为“Gossip启动引导节点”。
交易广播
在超级账本Fabric系统网络中,客户端节点负责构造并提交交易提案(TxProposal)请求,交易提案一般包含以下信息:
(1) ChannelID:交易所属的通道编号
(2) ChaincodeID:交易需要调用的链码(智能合约)
(3) Timestamp:交易的时间戳
(4) Sign:客户端签名
(5) TxPayload:交易所包含的事务,具体包括要调用的链码的函数及相关参数(Operation)、调用的相关属性(Metadata)等。
客户端节点会向已知的多个具有背书功能角色的Peer节点提交交易提案,Peer节点对接收到的交易提案请求进行验证,具体验证内容包括:
• 验证交易提案的格式是否正确;
• 验证交易是否重复提交;
• 验证交易提案中的客户端签名是否有效;
• 验证交易提案的发送方在相关通道中是否具有对应的执行权限。
Peer节点对交易提案验证通过后,将调用交易提案中相关的链码进行模拟执行,生成包含响应值、读/写集的事务结果,对结果进行背书并向客户端节点回复交易提案响应(ProposalResponse)消息。
当客户端节点收集到经过Peer节点背书的交易提案响应满足认可策略后,便基于收集到的经过背书的提案响应构建交易请求,并向Orderer节点广播交易请求。
Orderer节点接收到交易请求后,根据不同的通道,按时间顺序对它们进行排序,并组装新区块,之后将新区块广播给对应通道内的不同组织中的Leader节点。
区块广播与同步
Orderer节点将根据区块所属的通道ID,将新区块广播到同一通道中的Peer节点,Peer节点接收到新区块后,会先对区块进行验证,具体包括:
(1) 验证区块中的交易是否满足背书策略。
(2) 验证区块的数据是否正确。
(3) 验证区块中的每个交易,确保交易中的读/写集与状态数据库的数据一致。
通过Peer节点的上述验证后,新区块中的交易会被打上合法或非法交易的标签,然后将区块添加到通道对应的区块链上,同时把所有合法交易的读/写集中的“写”集合保存到状态数据库。
每个Peer节点都通过Gossip协议不断地接收来自多个节点已完成一致性的区块数据。为了保证安全和通道隔离性,每条传输的Gossip消息都有发送节点的签名,一方面杜绝恶意节点发出伪造消息,另一方面可以防止将消息分发给不在同一通道中的其它Peer节点。
新区块的传播过程如下:
(1) 某个Peer节点接收到一个需要传播给其他节点的新区块消息;
(2) 该Peer节点将消息发送给随机选择的预定数量的其它相连节点;
(3) 收到消息的Peer节点再将消息发送给(随机选择的)预定数量的其它相连节点(不包括发送消息的节点);
(4) 如此不断反复,直到每个Peer节点都收到消息。
共识层
首先要认识在超级账本Fabric系统中一次交易从客户端节点发起到被打包进区块,最终被写入区块链的全过程。
【8】
(1) 交易发起者通过客户端应用程序调用PKI CA证书服务进行注册和登记,并获取身份证书;
(2) 交易发起者通过客户端应用程序向超级账本Fabric系统区块链网络发起一个交易提案,交易提案包含本次交易要调用的链码名称、链码方法和参数信息以及交易签名等信息,并根据背书策略将交易提案发送给指定通道中的不同组织的背书Peer节点。
背书Peer节点对接收到的交易提案请求进行验证,验证通过后调用交易提案中相关链码进行模拟执行,得到交易响应结果,对结果进行背书后返回给客户端,注意此时区块链系统状态与账本数据并没有被真正修改。
客户端应用程序收到背书Peer节点返回的交易响应结果后,判断是否收到满足背书策略的足够多的背书结果,如果收到足够的背书,就将交易提案、交易响应和背书列表等信息打包组成一个交易并签名,然后发送给Orderer排序节点,否则交易失败,中止处理,该交易将被舍弃
(3) Orderer排序节点负责从区块链系统所有通道接收交易请求,分通道对“交易”按时间排序并打包成区块,然后将新区块广播给对应通道不同组织的Peer主节点。
(4) Peer主节点收到新区块后,会对区块中的区块数据部分包含的每笔交易进行验证,检查交易依赖的输入输出是否符合当前区块链的状态,验证背书策略是否满足,验证完成后将新区块追加到本地的区块链,更新账本,并修改世界状态。
(5) 各组织的同一通道的Peer节点之间会通过P2P网络协议相互同步区块链与账本数据,确保所有Peer节点本地的区块链与账本副本保持数据一致。
在超级账本Fabric系统中,所有交易在发送到区块链网络相关通道以后,都要经由Orderer排序节点对交易顺序进行共识排序,然后将交易按排好的顺序打包进区块,保证了任意一笔交易在区块链中的位置,以及在整个区块链网络中各节点的一致性和唯一确定性。
Fabric系统的共识服务由Orderer排序节点完成,并且允许多种共识算法以插件的形式应用于排序节点,系统默认提供Solo单节点共识、Kafka分布式队列共识等共识机制。
(1) Solo单节点共识
(2) Kafka分布式队列共识
【9】
Kafka是一个开源的分布式高可用消息队列系统,可以有序的管理消息并在多个冗余副本节点间保证数据一致性。当超级账本Fabric系统采用该共识机制时,会基于Kafka构建由多个Orderer排序节点组成的集群,提供基于Kafka集群的排序功能,支持CFT(Crash Fault Tolerence)容错(无恶意节点情况下的容错)和持久化,也可以进行扩展。
激励层
超级账本Fabric系统的设计初衷是用于构建联盟链,解决联盟中多组织之间的信任协作问题,区块链网络节点一般是由联盟主管机构或联盟中的多个组织提供和维护,超级账本Fabric系统内部不提供任何加密货币相关的发行和支付功能,因此,超级账本Fabric系统不提供与比特币、以太坊等系统的激励层功能。但是,在互联网环境中可以将超级账本Fabric系统与外部加密货币系统或第三方支付系统结合来实现类似的激励功能。
合约层
在超级账本Fabric系统中,智能合约称为“链码”(Chain Code),链码是一种遵循相关开发和部署规范的执行特定合约业务功能的可运行程序,系统合约层提供了对链码的全生命周期管理,涉及链码从开发到部署运行的整个过程。
l链码通过区块存储于区块链网络,能够独立运行在所属通道的Peer节点上的Docker容器中,以gRPC协议与相应的Peer节点进行通信,是对区块链系统与分布式账本中的数据进行增、删、改、查等操作的服务接口,可以根据不同的智能合约需求实现不同的复杂应用。
超级账本Fabric系统的链码分为两类:系统链码和用户链码。
(1) 系统链码
系统链码一般由超级账本Fabric开源项目社区开发与维护,只能采用Go语言开发,主要提供超级账本Fabric系统级功能,在区块链网络节点启动时会自动完成注册和部署。系统链码主要包括配置管理链码(CSCC)、生命周期管理链码(LSCC)、查询管理链码(QSCC)、交易背书链码(ESCC)和交易验证链码(VSCC)等5类。
• 配置管理链码(CSCC):负责处理网络Peer节点端的通道配置,包括加入新的通道和查询给定通道的对应配置等功能。
• 生命周期管理链码(LSCC):负责对用户链码的生命周期进行管理,管理在背书节点上的链码部署,主要包括链码的安装、实例化、升级等功能。
• 查询管理链码(QSCC):提供账本查询API,如获取区块链、区块、交易等信息。其提供的API接口包括根据交易号查询交易、根据区块号获取区块、根据区块哈希获取区块、根据交易号获取区块和根据通道名称获取最新区块链信息等。
• 交易背书管理链码(ESCC):负责背书(签名)过程,并支持对背书策略进行管理。对提交的交易提案的模拟运行结果进行签名,之后创建响应消息返回给客户端。
• 交易验证链码(VSCC):负责在记账前提供区块及交易的验证功能。
(2) 用户链码
用户链码与系统链码定位不同,系统链码实现超级账本Fabric系统的内置功能,而用户链码一般是由基于区块链的应用系统开发人员根据智能合约实际应用场景设计开发的链码,支持使用Go语言、Java语言、JavaScript语言来开发,在基于超级账本区块链的应用系统中具有重要地位和作用,用户链码对外为应用系统提供智能合约服务接口,对内可以对整个区块链系统与账本进行数据读写操作,如果一个应用系统没有通过用户链码与超级账本Fabric系统进行交互,这个应用系统就不是一个真正意义上的基于区块链的应用系统。
智能合约生命周期管理
在超级账本Fabric系统中,链码生命周期管理主要涉及用户链码的开发、安装、实例化、运行、升级等阶段,超级账本Fabric系统1.4版本和2.0版本在部分阶段略有不同,如图所示。
【10】
• 开发阶段:用户根据智能合约应用需求,使用Go语言、Java语言等设计开发链码程序,在链码程序中使用系统SDK接口操作区块链系统及账本,实现智能合约功能需求,代码开发,形成的Go语言、Java语言等编写的链码文件。
• 安装阶段:管理员指定链码的名称和版本号,将链码文件打包发送给网络Peer节点(背书节点),节点将链码包以链码名称和版本号的组合形式存储在本地特定的目录下。
• 实例化阶段:管理员指定通道、链码名称、版本号、背书策略和链码初始化函数,向已安装链码的Peer节点发起实例化请求,Peer节点从本地链码包获取链码文件。根据不同的链码语言,Peer节点使用对应语言的编译器编译链码文件,进而生成可执行文件,并将可执行文件打包生成一个Docker容器镜像,然后使用该镜像创建一个运行对应链码的容器,容器启动后链码与Peer节点之间通过gRPC进行通信。
• 运行阶段:在运行过程中,链码主要接收并处理客户端发起的交易操作。应用系统或用户通过客户端向Peer节点发起对应链码的调用请求,Peer节点将请求转发给链码。链码执行智能合约逻辑,对区块链系统及账本状态进行增、删、改、查等操作,并将执行结果返回给调用方。
• 升级阶段:根据智能合约应用需求的变化,链码的功能也随之需要扩展升级,该阶段主要是使用新的链码文件上传到Peer节点,然后生成新的链码镜像和容器。链码在升级过程中,链码名称必须要保持一致,链码版本号必须不同。