HyperLeger Fabric SDK开发(六)——resmgmt

HyperLeger Fabric SDK开发(六)——resmgmt

一、resmgmt简介

1、resmgmt简介

resmgmt支持在Fabric网络上创建和更新资源。resmgmt允许管理员创建、更新通道,并允许Peer节点加入通道。管理员还可以在Peer节点上执行与链码相关的操作,例如安装,实例化和升级链码。
官方文档:
https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt

2、resmgmt使用流程

resmgmt使用基本流程如下:
A、准备客户端上下文
B、创建资源管理客户端
C、创建新通道
D、将Peer节点加入通道
E、将链码安装到Peer节点的文件系统
F、在通道上实例化链码
G、查询通道上的Peer节点,已安装/实例化的链码等
使用示例:

// Create new resource management client
c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

// Read channel configuration
r, err := os.Open(channelConfig)
if err != nil {
    fmt.Printf("failed to open channel config: %s\n", err)
}
defer r.Close()

// Create new channel ‘mychannel‘
_, err = c.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r})
if err != nil {
    fmt.Printf("failed to save channel: %s\n", err)
}

peer := mockPeer()

// Peer joins channel ‘mychannel‘
err = c.JoinChannel("mychannel", WithTargets(peer))
if err != nil {
    fmt.Printf("failed to join channel: %s\n", err)
}

// Install example chaincode to peer
installReq := InstallCCRequest{Name: "ExampleCC", Version: "v0", Path: "path", Package: &resource.CCPackage{Type: 1, Code: []byte("bytes")}}
_, err = c.InstallCC(installReq, WithTargets(peer))
if err != nil {
    fmt.Printf("failed to install chaincode: %s\n", err)
}

// Instantiate example chaincode on channel ‘mychannel‘
ccPolicy := cauthdsl.SignedByMspMember("Org1MSP")
instantiateReq := InstantiateCCRequest{Name: "ExampleCC", Version: "v0", Path: "path", Policy: ccPolicy}
_, err = c.InstantiateCC("mychannel", instantiateReq, WithTargets(peer))
if err != nil {
    fmt.Printf("failed to install chaincode: %s\n", err)
}

fmt.Println("Network setup completed")
// output:
// Network setup completed

二、resmgmt常用接口

1、类型定义

定义链码提案类型

type chaincodeProposalType int

// Define chaincode proposal types
const (
   InstantiateChaincode chaincodeProposalType = iota
   UpgradeChaincode
)

定义安装链码请求

// InstallCCRequest contains install chaincode request parameters
type InstallCCRequest struct {
   Name    string
   Path    string
   Version string
   Package *resource.CCPackage
}

定义安装链码响应

// InstallCCResponse contains install chaincode response status
type InstallCCResponse struct {
   Target string
   Status int32
   Info   string
}

定义实例化链码请求

// InstantiateCCRequest contains instantiate chaincode request parameters
type InstantiateCCRequest struct {
   Name       string
   Path       string
   Version    string
   Args       [][]byte
   Policy     *common.SignaturePolicyEnvelope
   CollConfig []*common.CollectionConfig
}

定义实例化链码响应

// InstantiateCCResponse contains response parameters for instantiate chaincode
type InstantiateCCResponse struct {
   TransactionID fab.TransactionID
}

定义升级链码请求

// UpgradeCCRequest contains upgrade chaincode request parameters
type UpgradeCCRequest struct {
   Name       string
   Path       string
   Version    string
   Args       [][]byte
   Policy     *common.SignaturePolicyEnvelope
   CollConfig []*common.CollectionConfig
}

定义升级链码响应

// UpgradeCCResponse contains response parameters for upgrade chaincode
type UpgradeCCResponse struct {
   TransactionID fab.TransactionID
}

定义创建通道请求

//SaveChannelRequest holds parameters for save channel request
type SaveChannelRequest struct {
   ChannelID         string
   ChannelConfig     io.Reader             // ChannelConfig data source
   ChannelConfigPath string                // Convenience option to use the named file as ChannelConfig reader
   SigningIdentities []msp.SigningIdentity // Users that sign channel configuration
}

定义创建通道响应

// SaveChannelResponse contains response parameters for save channel
type SaveChannelResponse struct {
   TransactionID fab.TransactionID
}

2、配置签名接口

func MarshalConfigSignature(signature *common.ConfigSignature) ([]byte, error)
MarshalConfigSignature为由[]byte级联的给定客户端打包一个ConfigSignature(配置签名)。
func UnmarshalConfigSignature(reader io.Reader) (*common.ConfigSignature, error)
UnmarshalConfigSignature将从reader读取1个ConfigSignature为[]byte并将其解码。

3、获取资源管理客户端实例

type Client struct {
   ctx              context.Client
   filter           fab.TargetFilter
   localCtxProvider context.LocalProvider
}
func New(ctxProvider context.ClientProvider, opts ...ClientOption) (*Client, error)

New返回资源管理客户端实例。
使用示例:

ctx := mockClientProvider()

c, err := New(ctx)
if err != nil {
    fmt.Println("failed to create client")
}

if c != nil {
    fmt.Println("resource management client created")
}
// output:
// resource management client created

4、创建签名配置

func (rc *Client) CreateConfigSignature(signer msp.SigningIdentity, channelConfigPath string) (*common.ConfigSignature, error)
CreateConfigSignature为指定的客户端、自定义签名者、channelConfigPath参数的通道配置创建一个签名。
返回由SDK在内部签名的ConfigSignature对象,可以传递给WithConfigSignatures()选项。
func (rc *Client) CreateConfigSignatureData(signer msp.SigningIdentity, channelConfigPath string) (signatureHeaderData resource.ConfigSignatureData, e error)
CreateConfigSignatureData将准备一个SignatureHeader和用于签名通道配置的完整签名数据。
一旦SigningBytes在外部签名(使用OpenSSL等外部工具签署signatureHeaderData.SigningBytes),需要执行以下操作:
?A、创建一个common.ConfigSignature {}实例
?B、使用返回的字段‘signatureHeaderData.signatureHeader‘为其SignatureHeader字段赋值。
?C、使用外部工具生成的‘signatureHeaderData.signingBytes‘签名为其Signature字段赋值。
? D、然后使用WithConfigSignatures()选项传递此新实例以进行通道更新

5、安装链码

func (rc *Client) InstallCC(req InstallCCRequest, options ...RequestOption) ([]InstallCCResponse, error)
InstallCC允许管理员将链代码安装到Peer节点的文件系统上。如果未在选项中指定Peer节点,默认属于管理员MSP的所有Peer节点。
参数:
req包含必备的链码名称,路径,版本和背书策略的相关信息
options包含可选的请求选项
返回:Peer回复的安装链码提案的响应
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

req := InstallCCRequest{Name: "ExampleCC", Version: "v0", Path: "path", Package: &resource.CCPackage{Type: 1, Code: []byte("bytes")}}
responses, err := c.InstallCC(req, WithTargets(mockPeer()))
if err != nil {
    fmt.Printf("failed to install chaincode: %s\n", err)
}

if len(responses) > 0 {
    fmt.Println("Chaincode installed")
}
// output:
// Chaincode installed     

6、实例化链码

func (rc *Client) InstantiateCC(channelID string, req InstantiateCCRequest, options ...RequestOption) (InstantiateCCResponse, error)
InstantiateCC使用可选的自定义选项(指定Peer节点,过滤的Peer节点,超时)实例化链码。如果未在选项中指定Peer节点,则默认为所有通道Peer。
参数:
channelID是必备的通道名称
req包含必备的链码名称,路径,版本和背书策略的相关信息
options包含可选的请求选项
返回:带有交易ID的实例化链码响应
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

ccPolicy := cauthdsl.SignedByMspMember("Org1MSP")
req := InstantiateCCRequest{Name: "ExampleCC", Version: "v0", Path: "path", Policy: ccPolicy}

resp, err := c.InstantiateCC("mychannel", req)
if err != nil {
    fmt.Printf("failed to install chaincode: %s\n", err)
}

if resp.TransactionID == "" {
    fmt.Println("Failed to instantiate chaincode")
}

fmt.Println("Chaincode instantiated")
// output:
// Chaincode instantiated

7、加入通道

func (rc *Client) JoinChannel(channelID string, options ...RequestOption) error
JoinChannel允许Peer节点使用可选的自定义选项(指定Peer节点,已过滤的Peer节点)加入现有通道。如果未在选项中指定Peer节点,则将默认为属于客户端MSP的所有Peer节点。
参数:
channelID是必备的通道名称
options包含可选的请求选项
返回:如果加入通道失败,返回错误
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

err = c.JoinChannel("mychannel", WithTargets(mockPeer()))
if err != nil {
    fmt.Printf("failed to join channel: %s\n", err)
}

fmt.Println("Joined channel")
// output:
// Joined channel    

8、查询通道

func (rc *Client) QueryChannels(options ...RequestOption) (*pb.ChannelQueryResponse, error)
QueryChannels查询Peer节点已加入的所有通道的名称。
参数:
options包含可选的请求选项,注意,必须使用WithTargetURLs或WithTargets请求选项指定一个目标Peer节点。
返回:Peer节点加入的所有通道
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

response, err := c.QueryChannels(WithTargets(mockPeer()))
if err != nil {
    fmt.Printf("failed to query channels: %s\n", err)
}

if response != nil {
    fmt.Println("Retrieved channels")
}
// output:
// Retrieved channels        

9、获取通道配置

func (rc *Client) QueryConfigFromOrderer(channelID string, options ...RequestOption) (fab.ChannelCfg, error)
QueryConfigFromOrderer从orderer节点返回通道配置。如果没有使用选项提供orderer节点,则将默认为通道的orderer节点(如果已配置)或随机从配置中选取orderer节点。
参数:
channelID是必备的通道ID
options包含可选的请求选项
返回通道的配置

10、查询已安装链码

func (rc *Client) QueryInstalledChaincodes(options ...RequestOption) (*pb.ChaincodeQueryResponse, error)
QueryInstalledChaincodes查询Peer节点上已安装的链码。
参数:
options包含可选的请求选项。注意,必须使用WithTargetURLs或WithTargets请求选项指定一个目标Peer节点。
返回:指定Peer节点上已安装的链码列表
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

response, err := c.QueryInstalledChaincodes(WithTargets(mockPeer()))
if err != nil {
    fmt.Printf("failed to query installed chaincodes: %s\n", err)
}

if response != nil {
    fmt.Println("Retrieved installed chaincodes")
}
// output:
// Retrieved installed chaincodes      

11、查询已实例化链码

func (rc *Client) QueryInstantiatedChaincodes(channelID string, options ...RequestOption) (*pb.ChaincodeQueryResponse, error)
QueryInstantiatedChaincodes在指定的通道的Peer节点上的查询实例化链码。如果没有在选项中指定Peer节点,则将在此通道上随机查询一个Peer节点。
参数:
channelID是必填通道名称
options包含可选的请求选项
返回实例化链码列表
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

response, err := c.QueryInstantiatedChaincodes("mychannel", WithTargets(mockPeer()))
if err != nil {
    fmt.Printf("failed to query instantiated chaincodes: %s\n", err)
}

if response != nil {
    fmt.Println("Retrieved instantiated chaincodes")
}
// output:
// Retrieved instantiated chaincodes      

12、创建通道

func (rc *Client) SaveChannel(req SaveChannelRequest, options ...RequestOption) (SaveChannelResponse, error)
SaveChannel创建或更新通道。
参数:
req包含必备的通道名称和配置的相关信息
options包含可选的请求选项
?如果选项有签名(WithConfigSignatures()或1个或多个WithConfigSignature()调用),则SaveChannel将使用选项的签名而不是为req中找到的SigningIdentities创建一个签名。
确保req.ChannelConfigPath / req.ChannelConfig具有与签名匹配的通道配置。
返回带有交易ID的保存通道响应
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Printf("failed to create client: %s\n", err)
}

r, err := os.Open(channelConfig)
if err != nil {
    fmt.Printf("failed to open channel config: %s\n", err)
}
defer r.Close()

resp, err := c.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r})
if err != nil {
    fmt.Printf("failed to save channel: %s\n", err)
}

if resp.TransactionID == "" {
    fmt.Println("Failed to save channel")
}

fmt.Println("Saved channel")
// output:
// Saved channel

使用WithOrdererEndpoint

c, err := New(mockClientProvider())
if err != nil {
    fmt.Printf("failed to create client: %s\n", err)
}

r, err := os.Open(channelConfig)
if err != nil {
    fmt.Printf("failed to open channel config: %s\n", err)
}
defer r.Close()

resp, err := c.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r}, WithOrdererEndpoint("example.com"))
if err != nil {
    fmt.Printf("failed to save channel: %s\n", err)
}

if resp.TransactionID == "" {
    fmt.Println("Failed to save channel")
}

fmt.Println("Saved channel")
// output:
// Saved channel

13、升级链码

func (rc *Client) UpgradeCC(channelID string, req UpgradeCCRequest, options ...RequestOption) (UpgradeCCResponse, error)
UpgradeCC使用可选的自定义选项(指定Peer节点,过滤的Peer节点,超时)升级链码。如果没有在选项中指定Peer节点,则将默认为通道的所有Peer节点。
参数:
channelID是必备的通道名称
req包含必备的链码名称,路径,版本和背书策略的相关信息
options包含可选的请求选项
返回带有交易ID的升级链码响应
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

ccPolicy := cauthdsl.SignedByMspMember("Org1MSP")
req := UpgradeCCRequest{Name: "ExampleCC", Version: "v1", Path: "path", Policy: ccPolicy}

resp, err := c.UpgradeCC("mychannel", req, WithTargets(mockPeer()))
if err != nil {
    fmt.Printf("failed to upgrade chaincode: %s\n", err)
}

if resp.TransactionID == "" {
    fmt.Println("Failed to upgrade chaincode")
}

fmt.Println("Chaincode upgraded")
// output:
// Chaincode upgraded

14、为客户端设置过滤器

type ClientOption func(*Client) error

// WithDefaultTargetFilter option to configure default target filter per client
func WithDefaultTargetFilter(filter fab.TargetFilter) ClientOption

WithDefaultTargetFilter选项为每个客户端配置默认目标过滤器
使用示例:

ctx := mockClientProvider()

c, err := New(ctx, WithDefaultTargetFilter(&urlTargetFilter{url: "example.com"}))
if err != nil {
    fmt.Println("failed to create client")
}

if c != nil {
    fmt.Println("resource management client created with url target filter")
}
// output:
// resource management client created with url target filter   

15、RequestOption参数构建

//RequestOption func for each Opts argument
type RequestOption func(ctx context.Client, opts *requestOptions) error
type requestOptions struct {
   Targets       []fab.Peer                        // target peers
   TargetFilter  fab.TargetFilter                  // target filter
   Orderer       fab.Orderer                       // use specific orderer
   Timeouts      map[fab.TimeoutType]time.Duration //timeout options for resmgmt operations
   ParentContext reqContext.Context                //parent grpc context for resmgmt operations
   Retry         retry.Opts
   // signatures for channel configurations, if set, this option will take precedence over signatures of SaveChannelRequest.SigningIdentities
   Signatures []*common.ConfigSignature
}

func WithConfigSignatures(signatures ...*common.ConfigSignature) RequestOption

WithConfigSignatures允许为resmgmt客户端的SaveChannel调用提供预定义的签名。
func WithOrderer(orderer fab.Orderer) RequestOption
WithOrderer允许为请求指定一个orderer节点。
func WithOrdererEndpoint(key string) RequestOption
WithOrdererEndpoint允许为请求指定一个orderer节点。orderer将根据key参数查找。key参数可以是名称或url。
func WithParentContext(parentContext reqContext.Context) RequestOption
WithParentContext封装了grpc父对象上下文
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

clientContext, err := mockClientProvider()()
if err != nil {
    fmt.Println("failed to return client context")
    return
}

// get parent context and cancel
parentContext, cancel := sdkCtx.NewRequest(clientContext, sdkCtx.WithTimeout(20*time.Second))
defer cancel()

channels, err := c.QueryChannels(WithParentContext(parentContext), WithTargets(mockPeer()))
if err != nil {
    fmt.Printf("failed to query for blockchain info: %s\n", err)
}

if channels != nil {
    fmt.Println("Retrieved channels that peer belongs to")
}
// output:
// Retrieved channels that peer belongs to  

func WithRetry(retryOpt retry.Opts) RequestOption
WithRetry设置重试选项
func WithTargets(targets ...fab.Peer) RequestOption
WithTargets允许覆盖请求的目标Peer节点。
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

response, err := c.QueryChannels(WithTargets(mockPeer()))
if err != nil {
    fmt.Printf("failed to query channels: %s\n", err)
}

if response != nil {
    fmt.Println("Retrieved channels")
}
// output:
// Retrieved channels  

func WithTargetEndpoints(keys ...string) RequestOption
WithTargetEndpoints允许覆盖请求的目标Peer节点。目标由名称或URL指定,SDK将创建底层Peer节点对象。
func WithTargetFilter(targetFilter fab.TargetFilter) RequestOption
WithTargetFilter为请求启用目标过滤器。
使用示例:

c, err := New(mockClientProvider())
if err != nil {
    fmt.Println("failed to create client")
}

ccPolicy := cauthdsl.SignedByMspMember("Org1MSP")
req := InstantiateCCRequest{Name: "ExampleCC", Version: "v0", Path: "path", Policy: ccPolicy}

resp, err := c.InstantiateCC("mychannel", req, WithTargetFilter(&urlTargetFilter{url: "http://peer1.com"}))
if err != nil {
    fmt.Printf("failed to install chaincode: %s\n", err)
}

if resp.TransactionID == "" {
    fmt.Println("Failed to instantiate chaincode")
}

fmt.Println("Chaincode instantiated")
// output:
// Chaincode instantiated

func WithTimeout(timeoutType fab.TimeoutType, timeout time.Duration) RequestOption
WithTimeout封装了超时类型、超时时间的键值对到选项,如果未提供,则使用config的默认超时配置。

三、resmgmt示例

var (
   sdk           *fabsdk.FabricSDK
   org           = "org1"
   user          = "Admin"
)

// 区块链管理
func manageBlockchain() {
   // 表明身份
   ctx := sdk.Context(fabsdk.WithOrg(org), fabsdk.WithUser(user))

   cli, err := resmgmt.New(ctx)
   if err != nil {
      panic(err)
   }

   // 具体操作
   cli.SaveChannel(resmgmt.SaveChannelRequest{}, resmgmt.WithOrdererEndpoint("orderer.example.com"), resmgmt.WithTargetEndpoints())
}

原文地址:http://blog.51cto.com/9291927/2324692

时间: 2024-11-05 18:56:21

HyperLeger Fabric SDK开发(六)——resmgmt的相关文章

HyperLeger Fabric SDK开发(二)——Fabric SDK配置

HyperLeger Fabric SDK开发(二)--Fabric SDK配置 一.Fabric SDK配置 Fabric区块链网络应用程序需要大量的参数,用于连接Fabric区块链网络.通常将Fabric区块链网络应用程序所需的参数放到一个配置文件进行管理,配置文件定义Fabric SDK Go的配置和用户自定义参数,指定了连接Fabric区块链网络所需的全部信息,例如Fabric区块链网络组件的主机名和端口等.Fabric SDK GO为应用程序提供的配置文件通常使用yaml文件格式编写,

HyperLeger Fabric SDK开发(一)——Fabric SDK开发简介

HyperLeger Fabric SDK开发(一)--Fabric SDK开发简介 一.Fabric SDK简介 1.Fabric SDK简介 Farbric的Peer节点和Orderer节点都提供了基于gRPC协议的接口,用于和Peer节点与Orderer节点进行命令/数据交互.为了简化开发,为开发人员开发应用程序提供操作Fabric区块链网络的API,Fabric官方提供了多种语言版本的SDK.Fabric提供了三种语言版本的SDK,分别如下:A.Fabric Nodejs SDKB.Fa

HyperLeger Fabric SDK开发(三)——fabsdk

HyperLeger Fabric SDK开发(三)--fabsdk 一.fabsdk简介 1.fabsdk简介 fabsdk是Fabric SDK的主要包,fabsdk支持客户端使用Hyperledger Fabric区块链网络.fabsdk基于配置创建上下文环境,上下文环境会在client包使用.官方文档:https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/fabsdk 2.fabsdk使用基本流程 Fabsdk使用基本流程如

HyperLeger Fabric SDK开发(四)——channel

HyperLeger Fabric SDK开发(四)--channel 一.channel简介 1.channel?简介 pkg/client/channel支持访问Fabric网络上的通道.channel客户端实例提供与指定通道上的Peer节点进行交互的处理函数.channel客户端可以在指定通道上查询链码,执行链码以及注册或注销链码事件.如果应用程序需要与Fabric网络的多条通道进行交互,需要为每条通道创建一个单独的通道客户端实例.官方文档:https://godoc.org/github

HyperLeger Fabric SDK开发(八)——msp

HyperLeger Fabric SDK开发(八)--msp 一.msp简介 1.msp简介 msp支持在Fabric网络上创建和更新用户.MSP客户端支持以下操作:Enroll,Reenroll,Register,Revoke和GetSigningIdentity.官方文档:https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/msp 2.msp使用流程 msp使用的基本流程如下:A.准备客户端上下文B.创建msp

HyperLeger Fabric SDK开发(七)——ledger

HyperLeger Fabric SDK开发(七)--ledger 一.ledger简介 1.ledger简介 ledger包支持在Fabric网络上的指定通道上启用账本查询.如果应用程序需要对多个通道进行账本查询,需要为每个通道的账本客户端创建一个单独实例.账本客户端支持以下查询:QueryInfo,QueryBlock,QueryBlockByHash,QueryBlockByTxID,QueryTransaction和QueryConfig.官方文档:https://godoc.org/

HyperLeger Fabric开发(七)——HyperLeger Fabric链码开发

HyperLeger Fabric开发(七)--HyperLeger Fabric链码开发 一.链码开发模式 1.链码开发模式简介 Fabric的链码开发调试比较繁琐.在不使用链码开发模式的情况下,链码不能在本地测试,必须部署到docker,install和instantiate后,Peer节点会在新的容器中启动链码.但只能通过docker logs查看链码日志,通过打印日志的方式进行链码调试.如果对链码进行了修改,需要重新开始上述流程.为了简化Fabric链码开发的调试过程,Fabric引入了

HyperLeger Fabric开发(八)——HyperLeger Fabric链码开发测试

HyperLeger Fabric开发(八)--HyperLeger Fabric链码开发测试 一.链码实例 SACC项目链码实例如下: package main import ( "fmt" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/protos/peer" ) // SimpleAsset implements a si

HyperLeger Fabric开发(三)——HyperLeger Fabric架构

HyperLeger Fabric开发(三)--HyperLeger Fabric架构 一.HyperLeger Fabric架构简介 1.通道简介 商业应用的一个重要的需求是私密×××易,为此Fabric设计了通道(Channel)来提供成员之间的隐私保护.通道是部分网络成员之间拥有独立的通信渠道,在通道中发送的交易只有属于通道的成员才可见,因此通道可以看作是Fabric的网络中部分成员的私有通信子网.通道由排序服务管理.在创建通道的时候,需要定义通道的成员和组织.锚节点(anchor pee