Fabric go sdk开发入门

简介:

fabric go sdk是Hyperledger Fabric官方提供的Go语言开发包,应用程序可以利用fabric go sdk与fabric网络进行交互并访问链码。本教程介绍如何使用fabric go sdk实现链码的安装、实例化、交易提交
和状态查询等操作。

Hyperledger Fabric区块链开发教程:Fabric Node.js开发详解 | Fabric Java开发详解 | Fabric Golang开发详解

本文把与Hyperledger fabric网络交互的baas、应用程序、客户端统称成为客户端,它们可以使用fabric go sdk和fabric区块链网络进行交互,fabric go sdk调用grpc可以与指定的peer和orderer进行通信,本文的目的是在BYFN搭建的fabric网络的基础之上,展示如何使用fabric go sdk操作链码:

在这里插入图片描述

1、fabric go sdk简介

fabric go sdk是Fabric官方的Go语言SDK,它的目录结构如下:

在这里插入图片描述

有2个目录需要注意一下,internal和third_party,它们两个包含了fabric go sdk依赖的一些代码,来自于fabric、fabric-ca,当使用到fabric的一些类型时,应当使用以下的方式,而不是直接导入fabric或者fabric-ca:

import "github.com/hyperledger/fabric go sdk/third_party/github.com/hyperledger/fabric/xxx"

pkg目录是fabric go sdk的主要实现,doc文档介绍了不同目录所提供的功能,以及给出了接口调用样例:

  • pkg/fabsdk:主package,主要用来生成fabsdk以及fabric go sdk中其他pkg使用的option context。
  • pkg/client/channel:主要用来调用、查询Fabric链码,或者注册链码事件。
  • pkg/client/resmgmt:主要用来Hyperledger fabric网络的管理,比如创建通道、加入通道,安装、实例化和升级链码。
  • pkg/client/event:配合channel模块来进行Fabric链码事件的注册和过滤。
  • pkg/client/ledger:主要用来实现Fabric账本的查询,查询区块、交易、配置等。
  • pkg/client/msp:主要用来管理fabric网络中的成员关系。

3、使用fabric go sdk的一般步骤

  • 为client编写配置文件config.yaml
  • 为client创建fabric sdk实例fabsdk
  • 为client创建resource manage client,简称RC,RC用来进行管理操作的client, 比如通道的创建,链码的安装、实例化和升级等
  • 为client创建channel client,简称CC,CC用来链码的调用、查询以及链码事件 的注册和取消注册

4、fabric go sdk配置文件config.yaml概述

client使用sdk与fabric网络交互,需要告诉sdk两类信息:

  • 我是谁:即当前client的信息,包含所属组织、密钥和证书文件的路径等,
    这是每个client专用的信息。
  • 对方是谁:即fabric网络结构的信息,channel、org、orderer和peer等 的怎么组合起当前fabric网络的,这些结构信息应当与configytx.yaml中是一致的。这是通用配置,每个客户端都可以拿来使用。另外,这部分信息并不需要是完整fabric网络信息,如果当前client只和部分节点交互,那配置文件中只需要包含所使用到的网络信息。

在这里插入图片描述

5、使用go mod管理fabric go sdk项目的依赖

fabric go sdk目前本身使用go modules管理依赖,从go.mod可知,依赖的一些包指定了具体的版本,
如果你的项目依赖的版本和fabric go sdk依赖的版本不同,会产生编译问题。

因此建议项目也使用go moudles管理依赖,然后相同的软件包可以使用相同的版本,可以这样操作:

  • go mod init初始化好项目的go.mod文件。
  • 编写代码,完成后运行go mod run,会自动下载依赖的项目,但版本可能与 fabric go sdk中的依赖版本不同,编译存在问题。
  • 把go.mod中的内容复制到项目的go.mod中,然后保存,go mod会自动合并相同的依赖, 运行go mod tidy,会自动添加新的依赖或删除不需要的依赖。

6、创建fabric go sdk的入口实例

通过config.FromFile解析配置文件,然后通过fabsdk.New创建fabric go sdk的入口实例。

import "github.com/hyperledger/fabric go sdk/pkg/core/config"
import "github.com/hyperledger/fabric go sdk/pkg/fabsdk"

sdk, err := fabsdk.New(config.FromFile(c.ConfigPath))
if err != nil {
  log.Panicf("failed to create fabric sdk: %s", err)
}

7、创建fabric go sdk的资源管理客户端

管理员账号才能进行Hyperledger fabric网络的管理操作,所以创建资源管理客户端一定要使用管理员账号。

通过fabsdk.WithOrg("Org1")和fabsdk.WithUser("Admin")指定Org1的Admin账户,使用sdk.Context创建clientProvider,然后通过resmgmt.New创建fabric go sdk资源管理客户端。

import     "github.com/hyperledger/fabric go sdk/pkg/client/resmgmt"

rcp := sdk.Context(fabsdk.WithUser("Admin"), fabsdk.WithOrg("Org1"))
rc, err := resmgmt.New(rcp)
if err != nil {
  log.Panicf("failed to create resource client: %s", err)
}

8、创建fabric go sdk的通道客户端

使用用户账号创建fabric go sdk的通道客户端,以便进行fabric链码的调用和查询。使用sdk.ChannelContext创建channelProvider,需要指定channelID和用户User1,然后通过channel.New创建通道客户端,这个通道客户端就是调用channelID对应channel上链码的channel client。

import     "github.com/hyperledger/fabric go sdk/pkg/client/channel"

ccp := sdk.ChannelContext(ChannelID, fabsdk.WithUser("User1"))
cc, err := channel.New(ccp)
if err != nil {
  log.Panicf("failed to create channel client: %s", err)
}

9、使用fabric go sdk的资源管理客户端安装链码

安装Fabric链码使用资源管理客户端的InstallCC接口,需要指定resmgmt.InstallCCRequest以及在哪些peers上面安装。resmgmt.InstallCCRequest指明了链码ID、链码路径、链码版本以及打包后的链码。

打包链码需要使用到链码路径CCPath和GoPath,GoPath即本机的$GOPATH,CCPath是相对于GoPath的相对路径,如果路径设置不对,会造成sdk找不到链码。

// pack the chaincode
ccPkg, err := gopackager.NewCCPackage("github.com/hyperledger/fabric-samples/chaincode/chaincode_example02/go/", "/Users/shitaibin/go")
if err != nil {
  return errors.WithMessage(err, "pack chaincode error")
}

// new request of installing chaincode
req := resmgmt.InstallCCRequest{
  Name:    c.CCID,
  Path:    c.CCPath,
  Version: v,
  Package: ccPkg,
}

reqPeers := resmgmt.WithTargetEndpoints("peer0.org1.example.com")
resps, err := rc.InstallCC(req, reqPeers)
if err != nil {
  return errors.WithMessage(err, "installCC error")
}

10、使用fabric go sdk的资源管理客户端实例化链码

实例化链码需要使用fabric go sdk的资源管理客户端的InstantiateCC接口,需要通过ChannelID、
resmgmt.InstantiateCCRequest和peers,指明在哪个channel上实例化链码,请求包含了链码的ID、路径、版本,以及初始化参数和背书策略,背书策略可以通过cauthdsl.FromString生成。

// endorser policy
org1OrOrg2 := "OR('Org1MSP.member','Org2MSP.member')"
ccPolicy, err := cauthdsl.FromString(org1OrOrg2)
if err != nil {
  return errors.WithMessage(err, "gen policy from string error")
}

// new request
args := packArgs([]string{"init", "a", "100", "b", "200"})
req := resmgmt.InstantiateCCRequest{
  Name:    c.CCID,
  Path:    c.CCPath,
  Version: v,
  Args:    args,
  Policy:  ccPolicy,
}

// send request and handle response
reqPeers := resmgmt.WithTargetEndpoints("peer0.org1.example.com")
resp, err := rc.InstantiateCC(ChannelID, req, reqPeers)
if err != nil {
  return errors.WithMessage(err, "instantiate chaincode error")
}

11、使用fabric go sdk的资源管理客户端升级链码

再fabric go sdk中,升级链码和实例化链码是非常相似的,不同点只在请求是resmgmt.UpgradeCCRequest,调用的接口是rc.UpgradeCC:

// endorser policy
org1AndOrg2 := "AND('Org1MSP.member','Org2MSP.member')"
ccPolicy, err := c.genPolicy(org1AndOrg2)
if err != nil {
  return errors.WithMessage(err, "gen policy from string error")
}

// new request
args := packArgs([]string{"init", "a", "100", "b", "200"})
req := resmgmt.UpgradeCCRequest{
  Name:    c.CCID,
  Path:    c.CCPath,
  Version: v,
  Args:    args,
  Policy:  ccPolicy,
}

// send request and handle response
reqPeers := resmgmt.WithTargetEndpoints("peer0.org1.example.com")
resp, err := rc.UpgradeCC(ChannelID, req, reqPeers)
if err != nil {
  return errors.WithMessage(err, "instantiate chaincode error")
}

12、使用fabric go sdk的通道客户端调用链码

在fabric go sdk中,使用通道客户端的Execute接口调用链码,使用入参channel.Request和peers指明要让哪些peer上执行链码,进行背书。channel.Request指明了要调用的链码,以及链码内要Invoke的函数args,args是序列化的结果,序列化是自定义的,只要链码能够按相同的规则进行反序列化即可。

// new channel request for invoke
args := packArgs([]string{"a", "b", "10"})
req := channel.Request{
  ChaincodeID: c.CCID,
  Fcn:         "invoke",
  Args:        args,
}

// send request and handle response
// peers is needed
reqPeers := channel.WithTargetEndpoints("peer0.org1.example.com")
resp, err := cc.Execute(req, reqPeers)
if err != nil {
  return errors.WithMessage(err, "invoke chaincode error")
}
log.Printf("invoke chaincode tx: %s", resp.TransactionID)

13、使用fabric go sdk的通道客户端查询链码

在fabric go sdk中,查询和调用链码是非常相似的,使用相同的channel.Request,指明了Invoke链码中的query函数,然后调用cc.Query进行查询操作,这样节点不会对请求进行背书:

// new channel request for query
req := channel.Request{
  ChaincodeID: c.CCID,
  Fcn:         "query",
  Args:        packArgs([]string{keys}),
}

// send request and handle response
reqPeers := channel.WithTargetEndpoints(peer)
resp, err := cc.Query(req, reqPeers)
if err != nil {
  return errors.WithMessage(err, "query chaincode error")
}

log.Printf("query chaincode tx: %s", resp.TransactionID)
log.Printf("result: %v", string(resp.Payload))

小节

在这个教程中,我们介绍了fabric go sdk的一般使用步骤和sdk客户端的创建方法,以及如何利用fabric go sdk实现链码的安装、实例化、交易提交、状态查询等操作,并给出了相应的命令和示例代码。如果需要进一步学习fabric go sdk的应用开发技能,可以访问这个系统的教程
《Fabric Golang开发详解》


原文链接:fabric-sdk-go快速入门 — 汇智网

目录
相关文章
|
29天前
|
存储 设计模式 安全
Go语言中的并发编程:从入门到精通###
本文深入探讨了Go语言中并发编程的核心概念与实践技巧,旨在帮助读者从理论到实战全面掌握Go的并发机制。不同于传统的技术文章摘要,本部分将通过一系列生动的案例和代码示例,直观展示Go语言如何优雅地处理并发任务,提升程序性能与响应速度。无论你是Go语言初学者还是有一定经验的开发者,都能在本文中找到实用的知识与灵感。 ###
|
1月前
|
Serverless Go
Go语言中的并发编程:从入门到精通
本文将深入探讨Go语言中并发编程的核心概念和实践,包括goroutine、channel以及sync包等。通过实例演示如何利用这些工具实现高效的并发处理,同时避免常见的陷阱和错误。
|
2月前
|
安全 Go 开发者
破译Go语言中的并发模式:从入门到精通
在这篇技术性文章中,我们将跳过常规的摘要模式,直接带你进入Go语言的并发世界。你将不会看到枯燥的介绍,而是一段代码的旅程,从Go的并发基础构建块(goroutine和channel)开始,到高级模式的实践应用,我们共同探索如何高效地使用Go来处理并发任务。准备好,让Go带你飞。
|
2月前
|
存储 安全 Go
Go语言切片:从入门到精通的深度探索###
本文深入浅出地剖析了Go语言中切片(Slice)这一核心概念,从其定义、内部结构、基本操作到高级特性与最佳实践,为读者提供了一个全面而深入的理解。通过对比数组,揭示切片的灵活性与高效性,并探讨其在并发编程中的应用优势。本文旨在帮助开发者更好地掌握切片,提升Go语言编程技能。 ###
|
4月前
|
数据采集 开发工具 Python
海康威视工业相机SDK+Python+PyQt开发数据采集系统(支持软件触发、编码器触发)
该系统基于海康威视工业相机SDK,使用Python与PyQt开发,支持Gige与USB相机设备的搜索及双相机同时显示。系统提供软件触发与编码器触发模式,并可在数据采集过程中实时保存图像。此外,用户可以调节曝光时间和增益,并进行信息输入,这些信息将被保存至配置文件以便下次自动加载。参数调节与实时预览等功能进一步增强了系统的实用性。
251 1
|
4月前
|
Unix Go
Go从入门到放弃之时间操作
Go从入门到放弃之时间操作
|
4月前
|
机器学习/深度学习 移动开发 Linux
Go从入门到放弃之文件操作
Go从入门到放弃之文件操作
|
4月前
|
Java Go PHP
Go从入门到放弃之错误处理
Go从入门到放弃之错误处理
|
4月前
|
存储 Java Go
Go从入门到放弃之结构体(面向对象)
Go从入门到放弃之结构体(面向对象)
|
4月前
|
存储 机器学习/深度学习 设计模式
Go从入门到放弃之函数
Go从入门到放弃之函数