GO SDK Demo
本节提供了一个基于Go SDK的Demo,帮助用户开发自己的Go客户端应用程序。
准备工作
- 准备弹性云服务器。
- 在弹性云服务器上安装golang环境,Go版本要求:1.12及以上,1.16以下(>=1.12,<1.16)。
- 获取Go SDK源码,获取方法:登录区块链服务管理控制台,进入“应用案例”,单击“GO示例Demo-GO SDK Demo”中Go应用程序源码的“下载”按钮。
购买区块链实例
购买区块链实例,具体请参见实例部署-基于CCE集群。
安装及实例化链代码
本示例使用链代码文件获取方法:登录区块链服务管理控制台,进入“应用案例”,单击“GO示例Demo-GO SDK Demo”中Go语言示例链代码的“下载”按钮。
参考章节:用户指南-区块链管理-链代码管理。
下载SDK和证书
- 登录区块链服务管理控制台。
- 在“实例管理”页面,单击对应实例卡片上的“获取客户端配置”。
- 在新打开的页面,勾选“SDK文件”,SDK配置参数如下:
参数
值
链代码名称
chaincode
说明:链代码名称需要和链代码安装&实例化时的一致。
证书存放路径
/root/gosdkdemo/config
通道名称
channel
组织&Peer节点
保持系统默认
勾选“共识节点证书”。
勾选“Peer节点证书”,指定节点组织选择organization,勾选“管理员证书”。
- 单击“下载”。下载SDK配置文件、orderer组织的管理员证书和organization组织的管理员证书。
部署应用
- 将Go SDK源码下载至准备的弹性云服务器“/root”路径下并解压。
下载方法:登录区块链服务管理控制台,进入“应用案例”,单击“GO示例Demo-GO SDK Demo”中Go应用程序源码的“下载”按钮。
- 将下载SDK和证书步骤中的zip文件解压后,把configs文件夹中的orderer文件夹、peer文件夹、sdk-config.json、sdk-config.yaml文件全部复制到/root/gosdkdemo/config/目录下。
- 在代码中找到“/gosdkdemo/src/main.go”文件,进行以下修改:
- 将configFile中的值修改为实际的SDK配置文件名称,例如:demo-channel-sdk-config.yaml。
- 将org的值修改为organization对应的组织哈希值。
- 使用go mod方式配置GOPATH路径,请根据实际安装路径进行配置。
- 设置环境变量GO111MODULE为on。
export GO111MODULE=on
- go.mod文件如图所示,用户需要根据实际安装路径修改replace代码。
module main go 1.15 // 指定导入的依赖包及其版本 require ( github.com/bitly/go-simplejson v0.5.0 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869// indirect github.com/ghodss/yaml v1.0.0 github.com/hyperledger/fabric-sdk-go v1.0.0 github.com/pkg/errors v0.9.1 github.com/spf13/viper v1.7.1 ) // 以项目路径为/root/gosdkdemo/src为例 replace github.com/hyperledger/fabric-sdk-go => /root/gosdkdemo/src/github.com/hyperledger/fabric-sdk-go
- 设置环境变量GO111MODULE为on。
- 找到“gosdkdemo/src”路径下的main.go文件,执行如下命令:
go run main.go
通过内存传入私钥
如果用户需要对私钥文件进行加密,并在demo中解密后传入FabricSDK。
- 对于TLS私钥
在main.go文件的initializeSdk函数中,按如下方式调用函数:
encryptedtlsKey,err := GetTlsCryptoKey(org) //从配置文件指定路径下读取加密过的TLS私钥 //用户按照自行规定的加解密方法对encryptedtlsKey进行解密得到decryptedTlsKey字符串 SetClientTlsKey(decryptedTlsKey) //将解密后的TLS私钥传入Fabric-SDK,实现通过内存传入TLSKey
- 对于MSP私钥
在main.go文件的insert函数中,按如下方式调用函数:
encryptedbytekey,_:= GetPrivateKeyBytes(org) //从配置文件指定路径下读取加密过的MSP私钥 //用户按照自行规定的加解密方法对encryptedbytekey进行解密得到decryptedKey字符串 SetPrivateKey(decryptedKey) //将解密后的MSP私钥赋值给全局变量privateKey并通过该变量传入
常用API接口
Fabric-sdk-go的主要入口是FabricSDK类,这个可以通过NewSDK()方法分别可以生成。
Fabric-sdk-go的常用操作基本都可以用这四个client实现:FabricClient,ChannelClient,ChannelMgmtClient,ResourceMgmtClient。
- FabricSDK
FabricSDK在pkg\fabsdk\fabsdk.go中,通过New ()方法生成object。New ()方法支持可变参数Option,以下是生成FabricSDK的例子:
var opts []fabsdk.Option
opts = append(opts, fabsdk.WithOrgid(org))
opts = append(opts, fabsdk.WithUserName("Admin"))
sdk, err = fabsdk.New(config.FromFile(configFile), opts...)
configFile是SDK配置文件的路径。OrgId是SDK配置文件中的组织id。
FabricSDK在def/fabapi/fabapi.go中,通过NewSDK()方法生成object。NewSDK()方法有一个Options参数,以下是生成Options参数的例子:
deffab.Options{ConfigFile: configFile, LoggerFa logging.LoggerProvider(), UserName: sysadmin}
ConfigFile是SDK配置文件的路径。LoggerFactory是可选的,不提供的话default会log到console。
- FabricClient
FabricClient主要有以下常用的接口。
接口名称
描述
参数值
返回值
CreateChannel
创建Channel的接口,用于创建channel。
request
CreateChannelRequest
txn.TransactionID, error
QueryChannelInfo
查询Channel的接口,用于查询Channel的信息。
name string, peers
[]Peer
Channel, error
InstallChaincode
安装链码的接口,安装链码到区块链中。
request
InstallChaincodeRequest
[]*txn.TransactionPropos
lResponse, string, error
InstallChaincode
安装链码的接口,安装链码到区块链中。
request
InstallChaincodeRequest
[]*txn.TransactionPropos
lResponse, string, error
QueryChannels
查询channel的接口,查询区块链中已创建的通道。
peer Peer
*pb.ChannelQueryResponse, error
QueryInstalledChaincodes
查询已安装链码的接口,查询区块链中已安装的链码。
peer Peer
*pb.ChaincodeQueryResponse, error
- ChannelClient
ChannelClient主要包括链码查询和链码调用两类接口。
接口名称
描述
参数值
返回值
Query
链码查询接口,调用链码进行查询。
request
QueryRequest
[]byte, error
QueryWithOpts
带options的链码查询接口,与Query类似,但是可以通过QueryOpts指定notifier, peers,和timeout。
request
QueryRequest, opt
QueryOpts
[]byte, error
ExecuteTx
链码调用接口,用于链码的调用。
request
ExecuteTxRequest
TransactionID,
error
ExecuteTxWithOpts
带options的链码调用接口,与ExecuteTx类似,但是可以通过ExecuteTxOpts指定notifier, peers,和timeout。
request
ExecuteTxRequestopt ExecuteTxOpts
TransactionID,
error
- ChannelMgmtCLient
ChannelMgmtClient 只有两个接口SaveChannel(req SaveChannelRequest) error 和SaveChannelWithOpts(req SaveChannelRequest, opts SaveChannelOpts) error 这两个接口是用于创建channel用的,这两个接口里面具体实现会调用到FabricClient里createChannel()接口。
- ResourceMgmtClient
ResourceMgmtClient主要就是与链码生命周期相关的接口和一个peer加入通道的接口。
链码的删除接口为BCS增加的接口,目前只实现了删除链码安装包的功能。
接口名称
描述
参数值
返回值
InstallCC
安装链码,用于安装链码。
reqInstallCCRequest
[]InstallCCResponse, error
InstallCCWithOpts
带options的链码安装,与InstallCC类似,但是可以通过InstallCCOpts指定peers。
reqInstallCCRequest,opts InstallCCOpts
[]InstallCCResponse, error
InstantiateCC
实例化链码接口,用于实例化链码。
channelID string,reqInstantiateCCRequest
error
InstantiateCCWithOpts
带options的链码实例化,与InstantiateCC类似,但是可以通过InstantiateCCOpts指定peers和timeout。
channelID string,reqInstantiateCCRequest, optsInstantiateCCOpts
error
UpgradeCC
升级链码,用于链码的升级。
channelID string,reqUpgradeCCRequest
error
UpgradeCCWithOpts
带options的链码升级,与UpgradeCC类似,但是可以通过UpgradeCCOpts指定peers和timeout。
channelID string,reqUpgradeCCRequest, optsUpgradeCCOpts
error
DeleteCC
删除链码,用于链码的删除,目前只有删除安装包的功能。
channelID string,reqDeleteCCRequest
error
DeleteCCWithOpts
带options的链码删除,与DeleteCC类似,但是可以通过DeleteCCWithOpts指定peers和timeout。
channelID string,reqDeleteCCRequest,opts DeleteCCOpts
error
JoinChannel
Peers加入Channel的接口,用于peers加入Channel。
channelID string
error
JoinChannelWithOpts
带options的Peers加入Channel的接口,与JoinChannel类似,但是可以通过JoinChannelOpts指定peers。
channelID string,optsJoinChannelOpts
error
带options的接口都可以指定peers,peers可通过def/fabapi/pkgfactory.go 里的NewPeer(userName string, orgName string, url string, certificate string, serverHostOverride string, config config.Config) (fab.Peer, error) 生成。这个method比原生的NewPeer多两个参数userName, orgName, 这两个参数用于peer双向tls找到对应的tls证书。
调用合约
Main.go是一个简单的客户端应用示例程序,主要是为了方便用户熟悉客户端开发的流程,主要包含以下步骤:
//1.导入相关包:Sdk包中提供了一些API,以便用户的应用程序能够访问链代码。 import ( "fmt" "github.com/hyperledger/fabric-sdk-go/pkg/client/channel" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" …… ) //2.创建文件配置:这部分封装了应用开发必要的一些公共配置,包括sdk配置文件路径、组织名 var ( configFile = "/root/fabric-go-demo/config/go-sdk-demo-channel-sdk-config.yaml" org = "9103f17cb6b4f69d75982eb48bececcc51aa3125" …… ) //3.加载配置文件 loadConfig() //4. 初始化sdk initializeSdk() //5. 执行链代码,将数据写入账本,key = "testuser",value= "100" insert("insert",[][]byte{ []byte("testuser"), []byte("100"), }) //6.查询链代码,输出查询结果,key = "testuser" query("query", [][]byte{ []byte("testuser"), })
函数名 |
说明 |
---|---|
getOptsToInitializeSDK |
解析配置文件,创建并返回fabsdk.Option对象。 |
GetDefaultChaincodeId |
解析配置文件,返回chaincodeID。 |
GetDefaultChannel |
解析配置文件,返回channelID。 |
UserIdentityWithOrgAndName |
用户身份验证,输入为组织名和用户名,返回为验证结果。 |
ChannelClient |
创建*channel.Client对象,输入为组织名、用户名以及通道ID,返回*channel.Client对象。 |
insert |
将数据写入账本,输入参数为链码的对应方法名称以及要插入的键值对,返回为写入的结果。 |
query |
查询链上信息,输入参数为链码的对应方法名称以及要查询的数据,返回为查询的结果。 |