如何理解FabricSDK开发中的resmgmt-创新互联
如何理解Fabric SDK开发中的resmgmt,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名与空间、雅安服务器托管、营销软件、网站建设、南丰网站维护、网站推广。HyperLeger Fabric SDK开发
一、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()) }
看完上述内容,你们掌握如何理解Fabric SDK开发中的resmgmt的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
本文名称:如何理解FabricSDK开发中的resmgmt-创新互联
链接地址:http://hbruida.cn/article/ddidjd.html