1-Hyperledger Fabric概念详解
一.Hyperledger Fabric概述
Hyperledger Fabric是由IBM公司主导开发的一个面向企业级客户的开源项目。与比特币和以太坊这类公有链不同,Hyperledger Fabric 网络的成员需要从可信赖的 成员服务提供者(MSP)
注册经过授权认证后才能加入网络。从而避免了POW资源开销,大幅提高了交易处理效率。
二.基本术语
1.共享账本ledger
Hyperledger Fabric 中的账本由世界状态(world state)和区块链这两部分组成,它们彼此不同但却相互关联。其中世界状态由区块链决定。
-
世界状态是一个数据库(leveldb、couchdb),它存储了一组账本状态的当前值。通过世界状态,程序可以直接访问一个账本状态的当前值,不需要遍历整个交易日志来计算当前值。默认情况下,账本状态是以键值对的方式来表示的,因为我们可以创建、更新和删除状态,所以世界状态能够频繁更改。
-
区块链是交易日志,采用
Merkle Tree
结构,不可篡改,它记录了促成当前世界状态的所有改变。交易被收集在附加到区块链的区块中,能帮助我们理解所有促成当前世界状态的改变的历史。
2.通道Channel
通道是fabric中特别重要的概念。可大致理解为私有的子网络,通道中的节点共同维护账本,实现数据的隔离和保密。通道是特定网络成员之间的专用通信层,只能由被邀请加入通道的组织使用,并且对网络的其他成员不可见。每个channel对应一个账本,由加入该channel的peer维护,一个peer可以加入多个channel,维护多个账本。
3.组织Org
即Orginazation,管理一系列成员的组织。一个channel内可以有多个组织。
4.智能合约Chaincode
又称链码,Hyperledger Fabric 智能合约用 Go、Node.js 和 Java 语言编写,当该应用程序需要与账本交互时,由区块链外部的应用程序调用。在大多数情况下,链码只与账本的数据库、世界状态(例如,查询)交互,而不与交易日志交互。
5.背书Endorse
指一个节点执行了一个交易并对结果进行签名后返回响应的过程。
6.各种节点
6.1客户端节点
客户端必须连接到某一个peer节点或排序服务节点上才能与区块链网络进行通信。客户端向背书节点(endorser)提交交易提案(transaction proposal),收集到足够背书(可理解为担保)后,向排序服务广播交易提案,进行排序,生成区块。
6.2peer节点(包含Committer,Endorser,Leader,Anchor这几种状态)
- 提交节点(Committer):通道中的每个 Peer 节点都是一个提交节点。他们会接收生成的区块,在这些区块被验证之后会以附加的方式提交到 Peer 节点的账本副本中。
- 背书节点(Endorser):部分节点还会执行交易并对结果进行签名背书,背书节点是动态的角色,是与具体链码绑定的。每个链码在实例化的时候都会设置背书策略,指定哪些节点对交易背书后交易才是有效的。并且只有应用程序向它发起交易背书请求的时候才是背书节点,其他时候都是普通的提交节点,只负责验证交易并提交。背书节点也无法通过配置文件指定,而是由发起交易请求的客户端指定,背书节点可以有多个。
- 主节点(Leader):当组织在通道中具有多个 Peer 节点的时候,会有一个主节点,它负责将交易从排序节点分发到该组织中其他的提交节点。有两套选取主节点的方式,一套是静态选择的主节点,另一套是动态选举的主节点。对于静态选择,0个或者多个节点可以被配置为主节点。对于动态选举,一个节点会被选举成为主节点。另外,在动态选举主节点中,如果一个主节点出错了,那么剩下的节点将会重新选举一个主节点。
- 锚节点(Anchor):peer节点还可以是锚节点(anchor peer),锚节点主要负责代表组织和其他组织进行信息交换。每个组织都有一个锚节点,锚节点对于组织来说非常重要,如果锚节点出现问题,当前组织就会与其他组织失去联系。锚节点的配置信息是在
configtxgen模块
的配置文件configtx.yaml
中配置的。
6.3排序服务节点orderer
接收包含背书签名的交易,对未打包的交易进行排序生成区块,提供Gossip 协议的广播给peer节点。排序服务提供的是原子广播,保证同一个链上的节点接收到相同的信息,并且有相同的逻辑顺序,完成区块信息的同步工作。
6.4CA(Certificate Authority 证书颁发机构)节点
由服务器和客户端组成,CA节点接收客户端的注册申请,返回注册密码用于用户登录,以便获取身份证书。区块链上的所有操作都需要验证用户身份。
7.公钥基础结构PKI
PKI(Public Key Infrastructure),是一组互联网技术,可在网络中提供安全通信。
PKI有四个关键要素:数字证书,公钥和私钥,证书授权中心,证书撤销列表
8.成员服务提供者MSP
MSP(Membership Service Provider),一个 MSP 是定义管理该组织有效身份规则的组件。Fabric 中默认的 MSP 实现使用 X.509 证书作为身份,采用传统的公钥基础结构PKI分层模型。(PKI提供身份列表,MSP将身份转化为网络成员。)
要在Fabric网络上进行交易,成员需要这样做:
- 拥有一个由网络信任的CA颁发的身份。
- 成为一个被网络成员认可和认可的组织的成员。MSP将身份与组织的成员资格联系在一起。成员资格是通过将成员的公钥(也称为证书、签名证书或签证)添加到组织的MSP来实现的。
- 将MSP添加到网络上的一个联盟 或者通道。
- 确保MSP包括在网络中的策略 定义。
9.共识
在一个账本的更新被应用到 Peer 节点的本地账本之前, Peer 节点会请求网络中的其他 Peer 节点来批准这次更新。这个过程被称为共识
fabric中使用的共识可以分为:solo
;kafka
;PBFT
;Raft
(注:solo和kafka在fabric2.0版本中已被弃用,PBFT是fabric0.6版本)
(了解更多PBFT概念可以参考PBFT共识算法详解;了解更多Raft概念可以参考Raft共识算法详解)
共识包含如下三个阶段:
- 提案阶段:客户端向交易背书节点发送一个交易提案,背书节点通过交易模拟执行后返回给客户端背书结果及签名
- 排序和打包阶段:客户端将背书后的结果及签名交给排序节点排序并且打包进区块。
- 验证和提交阶段:排序节点生成区块向全网广播,记账节点收到这些区块后,先验证其正确性,验证通过后存入本地帐本中。
10.策略
策略是一组规则,用来定义如何做出决策和实现特定结果。策略是使 Hyperledger Fabric 不同于其他区块链系统(比如 Ethereum 或者 Bitcoin)的内容之一。在其他系统中,交易可以在网络中的任意节点生成和验证。治理网络的策略可以在任何时间及时修复,并且只可以使用和治理代码相同的方式进行变更。因为 Fabric 是授权区块链,用户由底层基础设施识别,所以用户可以在启动前决定网络的治理方式,以及改变正在运行的网络的治理方式。
三.交易流程
以下是fabric的经典交易流程,所有涉及到对账本数据更新的操作都是基于这个交易流程来完成的。
网络节点架构图
![image-20210512215500046](https://raw.githubusercontent.com/zmk-c/blogImages/master/img/fabric_%E6%9E%B6%E6%9E%84.png)
交易流程总图
![image-20210512215543027](https://raw.githubusercontent.com/zmk-c/blogImages/master/img/fabric_%E4%BA%A4%E6%98%93.png)
1.发送交易提案
应用程序使用相应的 SDK(Node,Java,Python,Golang)提供的 API 构建交易提案并提交给相应的背书节点,交易提案中包含:
channelID:通道信息
chaincodeID:要调用的链码信息
timestamp:时间戳
sign:客户端的签名
txPayload:提交的事务本身包含的内容,包含两项
operation:要调用的链码的函数及相应的参数
metadata:调用的相关属性
2.背书节点模拟执行交易提案
在接收来自客户端的消息时,背书节点首先验证客户端的签名clientSig(使用MSP),然后模拟事务。背书节点会调用链码模拟执行交易提案,产生包括响应值、读写集的事务结果(读写集是交易中记录的主要内容)。这些执行不会更新账本。
3.返回提案响应
背书节点会对读写集进行背书(Endorse)签名,生成提案响应(Proposal response)并返回给应用程序。
4.交易排序并分发
应用程序根据接收到的提案响应生成交易,并发送给排序服务节点(Orderer节点)。交易请求被提交到Ordering服务节点,该事务包含读/写,背书签名和通道ID;Orderer节点接收到事务请求之后,并不需要检查交易中的具体数据,它只是从网络中的所有通道接收交易,按时间顺序对它们进行全排序,并创建交易区块。之后广播给同一通道内所有组织的leader节点。
5.交易验证并提交
记账节点对接收到的区块进行验证(交易消息结构是否正确、是否重复、是否有足够的背书、读写集版本(防止了双花问题),通过验证后将结果写入到本地的分类账本中。验证不通过的交易会被标记无(Invalid)。
6.账本更新
每个peer节点都会将该块附加到通道链中,并且对于每个有效事务,写集都将提交到当前状态数据库。发出一个事件,以通知客户端应用程序交易(调用)已被不可变地附加到链上,并通知交易是否有效或无效。