欢迎订阅:《Fabric项目学习笔记》专栏
预备条件:
已搭建好的Fabric 1.4.4网络,本机安装go
代码来源:
https://github.com/togettoyou/fabric-realty
视频演示:
https://www.bilibili.com/video/BV1L8411H7aU/
使用云服务部署fabric:
https://realhahah.blog.csdn.net/article/details/126875483
注意:以下示例需要关闭TLS,在所有使用到的yaml文件里修改
1.首先启动BYFN网络
./byfn.sh up
2.在本机/etc/hosts 中填写Fabric网络节点的ip
ip orderer.example.com
ip peer0.org1.example.com
ip peer1.org1.example.com
ip peer0.org2.example.com
ip peer1.org2.example.com
3.创建目录与文件
mkdir gosdk && cd gosdk
mkdir blockchain
go mod init gosdk
4.向main.go写入以下内容
package main
import (
"fmt"
blk "gosdk/blockchain"
)
func invoke() {
var args [][]byte
args = append(args, []byte("a"))
args = append(args, []byte("b"))
args = append(args, []byte("10"))
res, err := blk.ChannelExecute("invoke", args)
if err != nil {
fmt.Printf("%v", err)
}
fmt.Printf("链码执行情况代码为:%v", res.ChaincodeStatus)
}
func query() {
var args [][]byte
args = append(args, []byte("a"))
res, _ := blk.ChannelQuery("query", args)
fmt.Printf("a的余额为:%v\n", string(res.Payload))
}
func main() {
blk.Init()
query()
invoke()
}
- 向config.yaml 写入以下内容
version: 1.0.0
# GO SDK使用的客户端部分。
client:
# 客户端所属的组织,必须是organizations定义的组织
organization: Org1
# 日志级别
logging:
level: info
# MSP证书的根路径
cryptoconfig:
path: ./crypto-config
# 通道定义
channels:
mychannel:
orderers:
- orderer.example.com
peers:
peer0.org1.example.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
peer1.org1.example.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
# 组织配置
organizations:
Org1:
mspid: "Org1MSP"
cryptoPath: peerOrganizations/org1.example.com/users/{username}@org1.example.com/msp
peers:
- peer0.org1.example.com
- peer1.org1.example.com
# orderer节点列表
orderers:
orderer.example.com:
url: orderer.example.com:7050
# 传递给gRPC客户端构造函数
grpcOptions:
ssl-target-name-override: orderer.example.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: true
# peers节点列表
peers:
# peer节点定义,可以定义多个
peer0.org1.example.com:
# URL用于发送背书和查询请求
url: peer0.org1.example.com:7051
# 传递给gRPC客户端构造函数
grpcOptions:
ssl-target-name-override: peer0.org1.example.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: true
peer1.org1.example.com:
url: peer1.org1.example.com:8051
grpcOptions:
ssl-target-name-override: peer1.org1.example.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: true
peer0.org2.example.com:
url: peer0.org2.example.com:9051
grpcOptions:
ssl-target-name-override: peer0.org2.example.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: true
peer1.org2.example.com:
url: peer1.org2.example.com:10051
grpcOptions:
ssl-target-name-override: peer1.org2.example.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: true
- 在blockchain目录,向sdk.go写入以下内容
package blockchain
import (
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
)
// 配置信息
var (
sdk *fabsdk.FabricSDK // Fabric SDK
configPath = "config.yaml" // 配置文件路径
channelName = "mychannel" // 通道名称
user = "Admin" // 用户
chainCodeName = "mycc" // 链码名称
endpoints = []string{"peer0.org1.example.com", "peer0.org2.example.com"} // 要发送交易的节点
)
// Init 初始化
func Init() {
var err error
// 通过配置文件初始化SDK
sdk, err = fabsdk.New(config.FromFile(configPath))
if err != nil {
panic(err)
}
}
// ChannelExecute 区块链交互
func ChannelExecute(fcn string, args [][]byte) (channel.Response, error) {
// 创建客户端,表明在通道的身份
ctx := sdk.ChannelContext(channelName, fabsdk.WithUser(user))
cli, err := channel.New(ctx)
if err != nil {
return channel.Response{}, err
}
// 对区块链账本的写操作(调用了链码的invoke)
resp, err := cli.Execute(channel.Request{
ChaincodeID: chainCodeName,
Fcn: fcn,
Args: args,
}, channel.WithTargetEndpoints(endpoints...))
if err != nil {
return channel.Response{}, err
}
//返回链码执行后的结果
return resp, nil
}
// ChannelQuery 区块链查询
func ChannelQuery(fcn string, args [][]byte) (channel.Response, error) {
// 创建客户端,表明在通道的身份
ctx := sdk.ChannelContext(channelName, fabsdk.WithUser(user))
cli, err := channel.New(ctx)
if err != nil {
return channel.Response{}, err
}
// 对区块链账本查询的操作(调用了链码的invoke),只返回结果
resp, err := cli.Query(channel.Request{
ChaincodeID: chainCodeName,
Fcn: fcn,
Args: args,
}, channel.WithTargetEndpoints(endpoints...))
if err != nil {
return channel.Response{}, err
}
//返回链码执行后的结果
return resp, nil
}
- 下载依赖文件
go mod tidy
- 拷贝crypto-config 目录到本地
tar -xzvf crypto-config.tar.gz
9.运行main.go文件
go run main.go