Fabric-SDK-Go

Fabric-SDK-Go

1.配置Fabric-SDK

1)创建config.yaml
确认 Hyperledger Fabric 基础网络环境运行没有问题后,现在我们通过创建一个新的 config.yaml 配置文件给应用程序所使用的 Fabric-SDK-Go 配置相关参数及 Fabric 组件的通信地址
进入项目的根目录中创建一个 config.yaml 文件并编辑
2)定义所需结构体
配置文件完成指定的配置信息之后,我们开始编写代码。
在项目的根目录下添加一个名为 sdkInit 的新目录,我们将在这个文件夹中创建 SDK,并根据配置信息创建应用通道;
为了方便管理 Hyperledger Fabric 网络环境,我们将在 sdkInit 目录中创建一个 fabricInitInfo.go 的源代码文件,用于定义一个结构体,包括 Fabric SDK 所需的各项相关信息

$ mkdir sdkInit
$ vim sdkInit/fabricInitInfo.go 

其源代码如下:

type InitInfo struct{
	ChannelID string
	ChannelConfig string
	OrgName string
	OrgAdmin string
	OrdererOrgName string
	OrgResMgmt *resmgmt.Client
}

声明好结构体的相应成员后,就可以使用Fabric-SDK-Go相关的API来创建SDK实例,并使用该SDK实例进行一系列的操作,例如:

  • 创建通道;
  • 将组织中的Peer加入已创建的通道中;
  • 安装链码;
  • 实例化链码;
  • 创建客户端实例。
  • List item

2. 创建Fabric-SDK

在 sdkInit 目录下新创建一个名为 start.go 的go文件利用 vim 编辑器进行编辑:

import (
	"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
	"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
	"fmt"
	"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
	mspclient "github.com/hyperledger/fabric-sdk-go/pkg/client/msp"
	"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp"
	"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"

)


const ChaincodeVersion  = "1.0"


func SetupSDK(ConfigFile string, initialized bool) (*fabsdk.FabricSDK, error) {

	if initialized {
		return nil, fmt.Errorf("Fabric SDK已被实例化")
	}

	sdk, err := fabsdk.New(config.FromFile(ConfigFile))
	if err != nil {
		return nil, fmt.Errorf("实例化Fabric SDK失败: %v", err)
	}

	fmt.Println("Fabric SDK初始化成功")
	return sdk, nil
}

func CreateChannel(sdk *fabsdk.FabricSDK, info *InitInfo) error {

	clientContext := sdk.Context(fabsdk.WithUser(info.OrgAdmin), fabsdk.WithOrg(info.OrgName))
	if clientContext == nil {
		return fmt.Errorf("根据指定的组织名称与管理员创建资源管理客户端Context失败")
	}

	// New returns a resource management client instance.
	resMgmtClient, err := resmgmt.New(clientContext)
	if err != nil {
		return fmt.Errorf("根据指定的资源管理客户端Context创建通道管理客户端失败: %v", err)
	}

	// New creates a new Client instance
	mspClient, err := mspclient.New(sdk.Context(), mspclient.WithOrg(info.OrgName))
	if err != nil {
		return fmt.Errorf("根据指定的 OrgName 创建 Org MSP 客户端实例失败: %v", err)
	}

	//  Returns: signing identity
	adminIdentity, err := mspClient.GetSigningIdentity(info.OrgAdmin)
	if err != nil {
		return fmt.Errorf("获取指定id的签名标识失败: %v", err)
	}

	// SaveChannelRequest holds parameters for save channel request
	channelReq := resmgmt.SaveChannelRequest{ChannelID:info.ChannelID, ChannelConfigPath:info.ChannelConfig, SigningIdentities:[]msp.SigningIdentity{adminIdentity}}
	// save channel response with transaction ID
	 _, err = resMgmtClient.SaveChannel(channelReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint(info.OrdererOrgName))
	if err != nil {
		return fmt.Errorf("创建应用通道失败: %v", err)
	}

	fmt.Println("通道已成功创建,")

	info.OrgResMgmt = resMgmtClient

	// allows for peers to join existing channel with optional custom options (specific peers, filtered peers). If peer(s) are not specified in options it will default to all peers that belong to client's MSP.
	err = info.OrgResMgmt.JoinChannel(info.ChannelID, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint(info.OrdererOrgName))
	if err != nil {
		return fmt.Errorf("Peers加入通道失败: %v", err)
	}

	fmt.Println("peers 已成功加入通道.")
	return nil
}

3. 测试创建通道
为了确保客户端能够初始化所有组件,将在启动网络的情况下进行简单的测试。 为了做到这一点,我们需要编写 Go 代码,在项目根目录下新创建一个 main.go 的主文件并编辑内容

const (
        configFile = "config.yaml"
        initialized = false
        SimpleCC = "simplecc"
)

func main() {

        initInfo := &sdkInit.InitInfo{

                ChannelID: "pronotarizationchannel",
                ChannelConfig: os.Getenv("GOPATH") + "/src/github.com/Pronotarization.com/fixtures/config/pronotarizationchannel.tx",

                OrgAdmin:"Admin",
                OrgName:"org1",
                OrdererOrgName: "orderer.Pronotarization.com",

        }

        sdk, err := sdkInit.SetupSDK(configFile, initialized)
        if err != nil {
                fmt.Printf(err.Error())
                return
        }

        defer sdk.Close()

        err = sdkInit.CreateChannel(sdk, initInfo)
        if err != nil {
                fmt.Println(err.Error())
                return
        }

}

4.使用Fabric-SDK-Go安装以及实例化链码
在start.go中声明一个InstallAndInstantiateCC函数,该函数的主要功能有三项:
1)安装链码;
2)实例化链码;
3)创建客户端实例。

func InstallAndInstantiateCC(
	sdk *fabsdk.FabricSDK,
	info *InitInfo) (*channel.Client, error) {
	fmt.Println("开始安装链码......")
	// creates new go lang chaincode package
	ccPkg, err := gopackager.NewCCPackage(info.ChaincodePath, info.ChaincodeGoPath)
	if err != nil {
		return nil, fmt.Errorf("创建链码包失败: %v", err)
	}

	//安装链码之前需要创建请求
	installCCReq := resmgmt.InstallCCRequest{
		Name:    info.ChaincodeID,
		Path:    info.ChaincodePath,
		Version: "0", //ChaincodeVersion
		Package: ccPkg}
	// allows administrators to install chaincode onto the filesystem of a peer
	_, err = info.OrgResMgmt.InstallCC(
		installCCReq,
		resmgmt.WithRetry(retry.DefaultResMgmtOpts))
	if err != nil {
		return nil, fmt.Errorf("安装链码失败: %v", err)
	}

	fmt.Println("指定的链码安装成功")
	fmt.Println("开始实例化链码......")

	//实例化链码之前需要创建请求
	ccPolicy := policydsl.SignedByAnyMember([]string{"this.OrgID"})
	instantiateCCReq := resmgmt.InstantiateCCRequest{
		Name:    info.ChaincodeID,
		Path:    info.ChaincodePath,
		Version: "0", //ChaincodeVersion
		Args:    [][]byte{[]byte("init")},
		Policy:  ccPolicy}
	// instantiates chaincode with optional custom options (specific peers, filtered peers, timeout). If peer(s) are not specified
	_, err = info.OrgResMgmt.InstantiateCC(
		info.ChannelID,
		instantiateCCReq,
		resmgmt.WithRetry(retry.DefaultResMgmtOpts))
	if err != nil {
		return nil, fmt.Errorf("实例化链码失败: %v", err)
	}

	fmt.Println("链码实例化成功")
	// 创建上下文
	clientChannelContext := sdk.ChannelContext(
		info.ChannelID,
		fabsdk.WithUser(info.UserName),
		fabsdk.WithOrg(info.OrgName))
	// 创建channel客户端
	// returns a Client instance. Channel client can query chaincode, execute chaincode and register/unregister for chaincode events on specific channel.
	channelClient, err := channel.New(clientChannelContext)
	if err != nil {
		return nil, fmt.Errorf("创建应用通道客户端失败: %v", err)
	}

	fmt.Println("通道客户端创建成功,可以利用此客户端调用链码进行查询或执行事务.")

	return channelClient, nil
}

5.在main中调用即可


今日推歌

----《东西》林俊呈

我开始美丽的际遇
你来自东或西
都没有太大的关系
都听你
因为始终和你前进
回忆并肩旅行
我愿意陪着你去东和西

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星回昭以烂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值