Fabric v2.4 新特性

作者 tinywell 日期 2021-12-21
Fabric v2.4 新特性

新功能简介

  • fabric 网关(fabric gateway)

fabric geteway 是一个运行在 peer 节点上的新服务,客户端可以通过 gateway 来进行交易的提交和运行,gateway 会进行背书节点的挑选、提案的发送、结果的组装等等,客户端几乎只需要提交交易请求就行了,这样客户端可以专注于业务逻辑而不用管 fabric 网络细节。

  • peer 退出通道(Peer node unjoin)

一个新的 peer node unjoin 子命令,允许 peer 节点退出某个通道,这样 peer 会移除这个通道相关的所有资源,并且不再接受这个通道的新区块了。👏🏻

  • 链码包 ID 计算(Calculate package ID of a packaged chaincode)

一个新的 peer lifecycle chaincode calculatepackageid 子命令,可以允许在不安装链码包的情况下,计算一个链码包的 ID。

  • 外部链码构建器(‘Chaincode as a service’ builder delivered with fabric-peer image)

fabric 在 2.0 的时候就支持外部运行的链码,但是需要自己准备外部链码构建器。这次新版本将一个外部链码构建器ccaas_builder 集成到项目中,并且预编译到了 peer 镜像,可以直接使用。

这些新功能中,fabric gateway无疑是个很大的改进,几乎取代了大部分 fabric sdk 的功能,极大的减轻了应用端的负担。其他的都是一些实用的小优化,尤其是 peer node unjoin ,终于可以给 peer 开后悔药了。

fabric gateway

fabric gateway 是 2.4 版本新引入到 peer 中的一个服务,专门用来跟 gateway sdk 配合来管理交易的提交和运行。gateway 服务提供以下几个 API:

  • 交易提案评估(Evaluate):就是执行查询类的交易(不会更新账本),挑选一个账本状态最新的节点执行交易,得到计算结果返回给客户端,gateway 会优先挑选组织内的节点,实在没有的话就挑一个其他组织的节点来执行;
  • 交易背书:gateway 的主要功能,对正常执行的交易,计算所需的一系列背书策略,包括常规的链码背书策略、私有数据集的背书策略以及状态库 key level 的签名策略,然后挑选满足背书策略的节点进行交易背书,拿到背书结果,并打包成待签名的交易信封返回给客户端;
  • 交易提交:客户端将签过名的交易信封交给 gateway,由 gateway 提交给 orderer 进行排序出块;
  • 交易状态:查询一笔交易的提交状态(交易合法性),如果交易还没有提交到账本则阻塞,直到提交为止;
  • 链码事件:监听链码事件,当有满足请求的新链码事件产生时,返回给客户端;

通过这几个 API 可以看出来,gateway 包揽了交易执行过程中的绝大部分事务,客户端只需要提交交易以及对交易信封进行签名,其他所有事情都有 gateway 代为完成,客户端不用再自己维护 fabric 网络状态,挑选节点等。
gateway 需要配合 gateway sdk 来使用。有了 gateway,sdk 其实也会很精简。目前 gateway sdk 支持Go、Node 和 Java,这些 SDK 都维护在一个项目库中,https://github.com/hyperledger/fabric-gateway

使用起来也非常方便,以 go sdk 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
func main() {
// Create gRPC client connection, which should be shared by all gateway connections to this endpoint.
clientConnection, err := grpc.Dial("gateway.example.org:1337", grpc.WithInsecure())
if err != nil {
panic(err)
}
defer clientConnection.Close()

// Create client identity and signing implementation based on X.509 certificate and private key.
id := NewIdentity()
sign := NewSign()

// Create a Gateway connection for a specific client identity.
gateway, err := client.Connect(id, client.WithSign(sign), client.WithClientConnection(clientConnection))
if err != nil {
panic(err)
}
defer gateway.Close()

// Obtain smart contract deployed on the network.
network := gateway.GetNetwork("channelName")
contract := network.GetContract("chaincodeName")

// Submit transactions that store state to the ledger.
submitResult, err := contract.SubmitTransaction("transactionName", "arg1", "arg2")
if err != nil {
panic(err)
}
fmt.Printf("Submit result: %s", string(submitResult))

// Evaluate transactions that query state from the ledger.
evaluateResult, err := contract.EvaluateTransaction("transactionName", "arg1", "arg2")
if err != nil {
panic(err)
}
fmt.Printf("Evaluate result: %s", string(evaluateResult))
}