P:Peer节点,背书功能(Endorser),执行交提案并背书,提交功能(commiteer):交易最终检查和落盘。
O:Orderer节点,排序功能,为全网收到的所有交易进行全局排序,并在Orderer节点间达成共识后生成区块。
Hyperledger Fabric基本概念
Peer:Peer节点组成区块链网络的基本单位(注,途中省略了Orderer节点)
ledger:共享账本,每一个节点都保存有相同的账本雷数据。
chanel:通道加入同一个通道的节点共享账本,不同的通道可以用来隔离数据。可以理解为子链。
Organization:组织,每一个对应一个区块链的参与方,一个组织对应N个节点。
Application:区块链应用,同一个区块链网络的不同组织可能对应不同的应用来完成不同的功能。
区块链应用即DAPP(Decentralized Application)需要连接到Peer节点和Orderer节点来与区块链网络通信。是交易天的发送者。
Fabric SDK应用程序中需要集成Fabric SDK来调用区块链网络。
华为云中一个区块链实例承载多个组织(节点)。它可以本身就是一个私有链网络,也可以邀请别的租户实例加入共同组成联盟链。
通道管理:增加新的通道,并选择节点加入通道。
成员管理:邀请其他租户加入联盟链。
通知管理:接受其他租户的邀请,可选择加入联盟链。
运维中心:使用云运维功能进行维护操作。
Hyperledger Fabric 定位:面向企业的分布式账本平台,创新地引入权限管理支持。设计上支持可插拔,可扩展是面向联盟链场景的开源项目。
主要概念和组件
分布式共享账本(shared ledger)
Append-only账本(区块链+世界状态)
P2P节点组成分布式系统
共识机制 交易执行-》排序-》校验及确认
智能合约:业务逻辑;无状态,确定性。
安全:身份管理、访问控制、隐私保护和通道隔离
共享账本(Ledger)
账本由两部分组成:世界状态,所有状态(state)的最新值。记录所有的交易历史。
按顺序执行所有的历史交易可推演出最新的状态值。
Block结构:文件系统方式存储
state状态: kv数据库维护支持levelDB,couchDB两种实现。
Hyperledger Fabric网络组成
Peer节点
- 背书功能(Endorser):执行交易提案并背书
- 提交功能(Committer):交易最终检查和落盘
- 领导节点(Leader Peer):拉取区块
- 锚节点(Anchor Peer):其他组织通信
Orderer节点:为交易进行全局排序,并生成区块
客户端:连接到Peer节点或Orderer节点,交易提案发送者
CA:负责向区块链网络的参与实体签发证书
通道:提供一种通讯机制,将peer和orderer链接在一起,形成一个具有保密性的通讯链路(虚拟):网络缺省包含一个账本(成为系统账本)和一个通道;子账本可以被创建,并绑定到一个通道
Fabric交易处理过程
Fabric中的智能合约
智能合约在Fabric中称为“链码”(Chaincode)
- 链码会对Fabric应用程序发送的交易做出响应,执行代码逻辑,与账本进行交互
- 链码会创建/修改/删除一些状态(state)并记录入账本中
- 链码在Fabric节点上的隔离沙盒(目前为Docker容器)中执行,通过gRPC协议与节点进行交互。必要的交互包括调用链码、读写账本、返回响应结果等
- Fabric支持多种计算机语言实现的链码,包括Golang、javaScript、Java等
每个链码都需要实现的接口
type Chaincode interface {
Init(stub ChaincodeStubInterface) pb.Response
Invoke(stub ChaincodeStubInterface) pb.Response
}
分为用户链码(user chaincode)和系统链码(system chaincode)
Fabric系统链码
负责区块链系统自身的处理逻辑,支持可编程和第三方实现
运行在节点主进程内
系统链码名称 | 功能介绍 | 是否支持链外调用 |
Configuration System Chaincode(CSCC) | 负责账本和链的配置管理 | 是 |
Endorsement System Chaincode(ESCC) | 负责背书签名过程 | 否 |
Lifecycle System Chaincode(LSCC) | 负责管理用户链码的生命周期 | 是 |
Query System Chaincode(QSCC) | 负责提供账本和链的信息查询功能,包括区块和交易等 | 是 |
Verification System Chaincode(VSCC) | 交易提交前根据背书策略进行检查,并对读写集合的版本进行验证 | 否 |
应用链码
智能合约封装了与区块链账本直接交互的相关过程,被应用程序调用
无状态的、事件驱动的代码,被调用时链码会自动执行合约逻辑
链码可操作账本中的状态,状态往往记录着与业务相关的重要数据(如资产的拥有者)
同一个区块链上可部署多个链码,应用程序通过指定名称、版本号、参数来调用发起交易
安全之多通道账本隔离
链 = Peers + Ledger + Ordering Channel
通道将参与者和数据(包含chaincode)进行隔离,提高隔离安全性
节点可加入不同的通道
一个Peer节点可以参与多个链
安全之权限和隐私
各层面的权限控制:网络,通道,交易...
面向商业活动的隐私保护:数据隐私(Hash,对称,非对称,同态,零知识证明等);审计
Fabric CA(PKI):身份注册管理,Fabric网络中的每个参与实体,通常用一个X.509证书确定身份;
MSP(MemBership Service Provider)用于抽象化组织中的身份规则,MSP使可验证身份成为了区块链网络的成员
链代码开发API
shim.ChaincodeSubInterface
提供了一系列API,供链码开发者在编写链码时灵活选择使用。
可分为四类:账本状态交互API、交易信息相关API、参数读取API、其他API。
输入参数读取API
API | 方法格式 | 说明 |
---|---|---|
GetArgs | GetArgs()[][]byte | 提取调用链码时交易Proposal中指定的参数,以字节串(Byte Array)数组形式返回。可以再Init或Invoke方法中使用。这些参数从ChaincodeSpec结构中的Input域直接提取 |
GetArgsSlice | GetArgsSlice() ([]byte, error) | 提取调用链码时交易Proposal中指定的参数,以字节串的形式返回。 |
GetFunctionAndParameters | GetFunctionAndParameters() (string, []string) | 提取调用链码时交易Proposal中指定的参数,其中第一个参数作为被调用的函数名称,剩下的参数作为函数的执行参数。 这是链码开发者和用户约定俗称的习惯,即在Init/Invoke方法中编写实现若干子函数,用户调用时以第一个参数作为函数名,链码中代码根据函数名称可以仅执行对应的分支处理逻辑 |
GetStringArgs | GetStringArgs() []string | 提取调用链码时交易Proposal中指定的参数,以字符串(String)数组形式返回 |
账本状态交互API
API | 方法格式 | 说明 |
---|---|---|
GetState | GetState(key string)([]byte, error) | 负责查询账本,返回指定键对应的值。 |
PutState | PutState(key string, value []byte) error | 尝试在账本中添加或更新一对键值。这一对键值会被添加到写集合中,等待Committer进一步的验证,验证通过后会真正写入到账本 |
DelState | DelState(key string) error | 在账本中删除一对键值。同样,将对键值的删除记录到交易提案的写集合中,等待Committer进一步的验证,验证通过后会真正写入到账本 |
GetStateByRange | GetStateByRange(startKey, endKey string) (StateQueryIteratorInterface, error) | 查询指定范围内的键值,startKey,endKey分别指定起始(包括)和终止(不包括),当为空时默认是最大范围。返回结果是一个迭代器StateQueryIteratorInterface结构,可以按照字典序迭代每个键值对,最后需调用Close()方法关闭 |
GetStateByPartialCompositeKey | GetStateByPartialCompositeKey(objectType string, keys []string) (StateQueryIteratorInterface, error) | 根据局部的复合键(前缀)返回所有匹配的键值。返回结果也是一个迭代器StateQueryIteratorInterface结构,可以按照字典序迭代每个键值对,最后需调用Close()方法关闭 |
GetHistoryForKey | GetHistoryForKey(key string) (HistoryQueryIteratorInterface, error) | 返回某个键的所有历史值。需要再节点配置中打开历史数据库特性 (ledger.history.enableHistoryDatabase = true) |
GetQueryResult | GetQueryResult(query string) (StateQueryIteratorInterface, error) | 对(支持富查询功能的)状态数据库进行富查询(rich query)。返回结果为迭代器结构StateQueryIteratorInterface.注意该方法不会被Committer重新执行进行验证,因此,不应该用于更新账本状态的交易中。目前仅有CouchDB类型的状态数据库支持富查询 |
交易信息相关API
API | 方法格式 | 说明 |
---|---|---|
GetTxID | GetTxID() string | 该方法返回交易提案中指定的交易ID。一般的,交易ID是客户端生成提案时候产生的数字摘要,由Nonce随机串和签名者身份信息,一起进行SHA256哈希运行生成 |
GetTxTimestamp | GetTxTimestamp()(*timestamp.Timestamp, error) | 返回交易被创建时的客户端打上的时间戳。这个时间戳是直接从交易ChannelHeader中提取的,所以在所有背书节点(endorsers)处看到的值都相同 |
GetBinding | GetBingding()([]byte, error) | 返回交易的binding信息。注意:交易的binding信息是将交易提案的nonse,Creator、epoch等信息组合起来,再进行哈希得到的数字摘要 |
GetSignedProposal | GetSignedProposal() (*pb.SignedProposal, error) | 返回该stub的SignedProposal结构,包括了跟交易提案相关的所有数据 |
GetCreator | GetCreator()([]byte, error) | 返回该交易的提交者的身份信息,从signedProposal中的SignatureHeader.Creator提取 |
GetTransient | GetTransient()(map[string][]byte, error) | 返回交易中带有的一些临时信息,从ChaincodeProposalPayload.transient域提取,可以存放一些应用相关的保密信息,这些信息不会被写到账本中 |
其它API
API | 方法格式 | 说明 |
---|---|---|
CreateCompositeKey | CreateCompositeKey(objectType string, attributes []string) (string, error) | 给定一组属性(attributes),该API将这些属性组合起来构造返回一个复合键。返回的复合键可以被PutState等方法使用。objectType和attributes只允许合法的utf8字符串,并且不能包含U+0000和U+10FFFF |
SplitCompositeKey | SplitCompositeKey(compositeKey string) (string, []string, error) | 该方法与CreateCompositeKey方法对应,给定一个复合键,将其拆分为构造复合键时所用的属性 |
InvokeChaincode | InvokeChaincode(chaincodeName string, args[][]byte, channel string) pb.Response | 如果channel为空,则默认为当前通道。调用另一个链码中的Invoke方法,如果被调用链码在同一个通道内,则添加其读写集合信息到调用交易;否则执行调用但不影响读写集合信息。 目前仅限于读操作,同时不会生成新的交易 |
SetEvent | SetEvent(name string, payload []byte) error | 设定当这个交易在Committer处被认证通过,写入到区块时发送的事件(event) |