遇到bug, 未完待续!!!
写在最前
前序博客已经介绍了使用命令的方式在Fabric上创建通道以及部署执行链码的方法,但这个过程太繁琐,尤其是当Fabric网络中peer节点和组织Org过多时,需要频繁的更改环境变量。
Hyperledger Fabric官方提供了Fabric-sdk-go
(也有针对其他语言的sdk)使开发人员能够与Fabric网络进行交互,并且可基于此构建区块链技术的应用程序。本篇博客主要介绍Fabric-sdk-go
的简单使用。
基本环境
本机操作系统为MAC系统,和Fabric运行在虚拟机中。Fabric的具体运行环境为:
操作系统:Ubuntu 16.04
版本:Hyperledger Fabric: V2.5.4
1 GoLand连接虚拟机
要使用ssh方式连虚拟机之前,需要在两个系统上安装ssh服务。无论是在MAC上安装ssh
,还是在Ubuntu系统上安装ssh
,网络上资料都很多,这里不在赘述。
1.1 在MAC上使用ssh连接虚拟机
为了保证后续能顺利使用Goland连接虚拟机,这里先在MAC上使用ssh连接虚拟机。首先要保证本机系统上和虚拟机上的Ubuntu系统上的ssh
服务都是开启状态。接着本机系统的终端上尝试连接虚拟机,具体指令如下:
bash
ssh sherry@172.16.8.129
其中@前的部分为Ubuntu系统的用户名。@后面的ip地址可以在Ubuntu系统上通过ifconfig
命令进行查询,具体如下:
上述命令运行成功之后,将可以在MAC的终端上操作Ubuntu系统。具体如下:
1.2 GoLand连接Fabric网络
1.2.1 启动Fabric网络
Fabric-sdk-go
不能创建Fabric网络,所以Fabric网络的创建过程仍然在Ubuntu系统中来创建。为了简便,使用fabric-samples
提供的测试网络test-network
,其创建如下。
bash
sudo ./network.sh up
docker ps -a
其结果如下:
1.2.2 Goland连接Fabric网络
使用Goland连接Fabric网络需要完成以下几件事情:
-
Goland连接虚拟机。
在Goland中,打开Tools->Deployment->configuration进入Deployment界面,这里要新建一个SFTP部署。具体如下:
connecton
其中
ssh configuration
的配置界面如下:
-
在Goland中配置Fabric网络文件映射目录。
这里的Deployment path
即为Ubuntu系统上Fabric网络的相对路径地址(根路径为/home/sherry
)。而local path
即为Deployment path
中的文件在本地系统上的映射地址。 -
接着启动ssh连接。具体如下:
之后便可以在Goland中操作Ubuntu系统了。具体如下:
-
接着为了能在GoLand中修改链码及编写代码。先将Fabric网络中的文件映射到本地系统上。具体如下:
Tips:在文件同步时可能会出错,可以先在Ubuntu系统上更改Fabric网络文件的权限,再重新进行同步。
2 使用Fabri-SDK-GO操作网络
2.1 准备工作
- 在Ubuntu系统上搭建
finance
网络。具体搭建过程可以参考博客:https://blog.csdn.net/yeshang_lady/article/details/134113296 - 修改Goland的ssh部署。将
finance
网络所在的Ubuntu目录映射到GoLand的Fabric_GOPATH
目录上,并将finance
网络的所有文件下载到Fabric_GOPATH
目录上。 - 准备链码文件。在
Fabric_GOPATH
上创建usersChaincode/chaincode
目录来保存链码文件asset-transfer.go
。asset-transfer.go
文件参考博客:https://blog.csdn.net/yeshang_lady/article/details/134801201 - 配置相关包。在
Fabric_GOPATH/userChaincode/
下执行如下代码(在GoLand->Terminal->local
中执行):
bash
go mod init
vim go.mod #这里要修改go.mod文件,将go语言版本修改为1.21
go get github.com/hyperledger/fabric-contract-api-go/contractapi
go get github.com/hyperledger/fabric-sdk-go
GO111MODULE=on go mod vendor
- 为了保证Fabric-sdk-go的顺利执行,进入如下
vendor/github.com/hyperledger
目录,git
命令下载fabric-sdk-go
源文件。具体如下:
bash
git clone https://github.com/hyperledger/fabric-sdk-go.git
如果不进行这一步操作,后续使用fabric-sdk-go创建客户端的时候会可能会遇到如下错误:
..\vendor\github.com\hyperledger\fabric-sdk-go\internal\github.com\hyperledger\fabric\discovery\client\api.go:47:38: undefined: discovery.ChaincodeCall
- 在
Fabric_GOPATH\usersChaincode
下创建sdkInit
目录并创建start.go
文件。后续所有与Fabric-SDK-GO操作相关的代码都存放在该文件中。 - 在
Fabric_GOPATH\usersChaincode
下闯将main.go
文件作为主函数所在的文件。
2.2 实例化Fabri SDK
在实例化Fabric SDK之前,需要在Fabric_GOPATH/usersChaincode
下生成config.yaml
文件。finance
网络对应的config.yaml
文件如下(Fabric-sdk-go中给了一些样例文件可以参考):
yaml
# Copyright SecureKey Technologies Inc. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
version: 1.0.0
client:
organization: org1 #此应用程序的所有者
logging:
level: info
cryptoconfig:
path: ${GOPATH}/src/Fabric_GOPATH/organizations
credentialStore:
path: "/tmp/state-store"
cryptoStore:
path: /tmp/msp
BCCSP:
security:
enabled: true
default:
provider: "SW"
hashAlgorithm: "SHA2"
softVerify: true
level: 256
tlsCerts:
systemCertPool: true
client:
key:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org1.finance.com/users/Admin@org1.finance.com/tls/client.key
cert:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org1.finance.com/users/Admin@org1.finance.com/tls/client.crt
channels:
channel1:
peers:
peer0.org1.finance.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
peer1.org1.finance.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
peer0.org2.finance.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
policies:
queryChannelConfig:
minResponses: 1
maxTargets: 1
retryOpts:
attempts: 5
initialBackoff: 500ms
maxBackoff: 5s
backoffFactor: 2.0
selection:
SortingStrategy: BlockHeightPriority
Balancer: RoundRobin
BlockHeightLagThreshold: 5
eventService:
resolverStrategy: MinBlockHeight
balancer: RoundRobin
blockHeightLagThreshold: 4
reconnectBlockHeightLagThreshold: 8
peerMonitorPeriod: 6s
organizations:
org1:
mspid: Org1MSP
cryptoPath: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org1.finance.com/users/Admin@org1.finance.com/msp
peers:
- peer0.org1.finance.com
- peer1.org1.finance.com
certificateAuthorities:
- ca.org1.finance.com
org2:
mspid: Org2MSP
cryptoPath: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org2.finance.com/users/Admin@org2.finance.com/msp
peers:
- peer0.org2.finance.com
certificateAuthorities:
- ca.org2.finance.com
orderers:
orderer.finance.com:
url: orderer.finance.com:7050
grpcOptions:
ssl-target-name-override: orderer.finance.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/ordererOrganizations/finance.com/tlsca/tlsca.finance.com-cert.pem
peers:
-defaults:
grpcOptions:
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
peer0.org1.finance.com:
url: peer0.org1.finance.com:7051
grpcOptions:
ssl-target-name-override: peer0.org1.finance.com
tlsCACerts:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org1.finance.com/tlsca/tlsca.org1.finance.com-cert.pem
peer1.org1.finance.com:
url: peer1.org1.finance.com:8051
grpcOptions:
ssl-target-name-override: peer1.org1.finance.com
tlsCACerts:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org1.finance.com/tlsca/tlsca.org1.finance.com-cert.pem
peer0.org2.finance.com:
url: peer0.org2.finance.com:9051
grpcOptions:
ssl-target-name-override: peer0.org2.finance.com
tlsCACerts:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org2.finance.com/tlsca/tlsca.org2.finance.com-cert.pem
certificateAuthorities:
ca.org1.finance.com:
url: https://ca.org1.finance.com:7054
grpcOptions:
ssl-target-name-override: ca.org1.finance.com
tlsCACerts:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org1.finance.com/tlsca/tlsca.org1.finance.com-cert.pem
client:
key:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org1.finance.com/users/Admin@org1.finance.com/tls/client.key
cert:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org1.finance.com/users/Admin@org1.finance.com/tls/client.crt
registrar:
enrollId: admin
enrollSecret: adminpw
caName: ca.org1.finance.com
ca.org2.finance.com:
url: https://ca.org2.finance.com:9054
grpcOptions:
ssl-target-name-override: ca.org2.finance.com
tlsCACerts:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org2.finance.com/tlsca/tlsca.org2.finance.com-cert.pem
client:
key:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org2.finance.com/users/Admin@org2.finance.com/tls/client.key
cert:
path: ${GOPATH}/src/Fabric_GOPATH/organizations/peerOrganizations/org2.finance.com/users/Admin@org2.finance.com/tls/client.crt
registrar:
enrollId: admin
enrollSecret: adminpw
caName: ca.org2.finance.com
在start.go
文件中添加如下代码:
go
/*代码的import部分会自己生成,这里为了节省空间就不在展示了*/
package sdkInit
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
}
在main.go
中添加如下代码,具体如下:
go
const (
configFile = "config.yaml"
initialized = false
)
func main() {
sdk, err := sdkInit.SetupSDK(configFile, initialized)
if err != nil {
fmt.Println(err.Error())
return
}
defer sdk.Close() //
}
运行main.go
文件即可完成Fabric SDK的实例化。