zoukankan      html  css  js  c++  java
  • Fabric-sdk-go操作Chaincode

    因为工作的需要,最近了解了下如何通过sdk来操作Chaincode,本文是sdk使用时的一些操作总结。

    在fabric网络启动过程中,一般分为“启动网络 -> 创建通道 -> 加入通道 -> 安装链码 -> 实例化链码 -> 调用链码”。本文以fabric-sdk-go项目中的end_to_end.go为例,介绍如何通过fabric-sdk-go来使用链码。

    创建sdk实例

    使用sdk的第一步是创建sdk实例

    sdk, err := fabsdk.New(configOpt, sdkOpts...)
    if err != nil {
    	t.Fatalf("Failed to create new SDK: %s", err)
    }
    defer sdk.Close()
    

    创建通道并安装链码

    end_to_end.go中,这一步是通过createChannelAndCC()来实现的。

    首先是使用提供的身份凭证来创建事务用于之后的操作:

    clientContext := sdk.Context(fabsdk.WithUser(orgAdmin), fabsdk.WithOrg(ordererOrgName))
    

    接着使用上一步创建的事务来创建一个资源管理客户端(resmgmt.Client)

    resMgmtClient, err := resmgmt.New(clientContext)
    

    接着createChannel()创建通道。在创建通道时,需要使用该组织的管理员用户创建,主要用到GetSigningIdentity()SaveChannel()方法:

    func createChannel(t *testing.T, sdk *fabsdk.FabricSDK, resMgmtClient *resmgmt.Client) {
    	mspClient, err := mspclient.New(sdk.Context(), mspclient.WithOrg(orgName))
    	if err != nil {
    		t.Fatal(err)
    	}
    	adminIdentity, err := mspClient.GetSigningIdentity(orgAdmin)
    	if err != nil {
    		t.Fatal(err)
    	}
    	req := resmgmt.SaveChannelRequest{ChannelID: channelID,
    		ChannelConfigPath: integration.GetChannelConfigTxPath(channelID + ".tx"),
    		SigningIdentities: []msp.SigningIdentity{adminIdentity}}
    	txID, err := resMgmtClient.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com"))
    	require.Nil(t, err, "error should be nil")
    	require.NotEmpty(t, txID, "transaction ID should be populated")
    }
    

    加入通道

    通道创建成功后,需要将将组织添加到通道中,主要用到JoinChannel()

    adminContext := sdk.Context(fabsdk.WithUser(orgAdmin), fabsdk.WithOrg(orgName))
    
    // Org resource management client
    orgResMgmt, err := resmgmt.New(adminContext)
    ......
    
    	// Org peers join channel
    err = orgResMgmt.JoinChannel(channelID, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")) 
    ......
    

    创建链码

    完成上述的操作,接下来就是链码相关的操作了。

    与命令行下的链码操作不同,sdk安装链码时并不需要事先将链码程序放到背书节点,而是在调用InstallCCRequest()时再将本地的链码打包安装到背书节点:

    func createCC(t *testing.T, orgResMgmt *resmgmt.Client) {
        // Packing the example cc from local
        // argv[0]: cc path in local
        // argv[1]: GOPATH
    	ccPkg, err := packager.NewCCPackage("github.com/example_cc", integration.GetDeployPath())
    	......
    	// Install example cc to org peers
    	installCCReq := resmgmt.InstallCCRequest{Name: ccID, Path: "github.com/example_cc", Version: "0", Package: ccPkg}
    	_, err = orgResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts))
    	......
    	// Set up chaincode policy
    	ccPolicy := cauthdsl.SignedByAnyMember([]string{"Org1MSP"})
    	// Org resource manager will instantiate 'example_cc' on channel
    	resp, err := orgResMgmt.InstantiateCC(
    		channelID,
    		resmgmt.InstantiateCCRequest{Name: ccID, Path: "github.com/example_cc", Version: "0", Args: integration.ExampleCCInitArgs(), Policy: ccPolicy},
    		resmgmt.WithRetry(retry.DefaultResMgmtOpts),
    	)
    	......
    }
    

    链码调用

    链码调用,这里推荐使用Execute()

    func executeCC(t *testing.T, client *channel.Client) {
    	_, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "invoke", Args: integration.ExampleCCDefaultTxArgs()},
    		channel.WithRetry(retry.DefaultChannelOpts))
    	if err != nil {
    		t.Fatalf("Failed to move funds: %s", err)
    	}
    }
    

    示例

    这个例子是使用sdk操作fabric-samples中的fabcar链码,其中省略了创建和加入通道的操作。

    执行go run main.go后,输出结果如下:

    result

    本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可。

  • 相关阅读:
    济南空中课堂视频下载辅助脚本
    npm 修改仓库源
    Java后端实现登陆的方式
    java 新词汇
    数据库系统,设计、实现与管理(基础篇)阅读笔记
    java 面试01
    js rem 适配多端
    了解Java
    linux 查看内存使用情况
    linux 日志查看
  • 原文地址:https://www.cnblogs.com/lianshuiwuyi/p/13125446.html
Copyright © 2011-2022 走看看