Hyperledger Fabric初学者:如何用Golang开发Web服务调用链码?
用Golang开发Web服务调用Hyperledger Fabric链码指南
嘿,恭喜你已经搞定了Fabric基础网络搭建和链码安装这关键的第一步!接下来咱们一步步实现用Golang写Web服务来调用链码的需求,核心思路是利用Fabric Go SDK和区块链网络交互,再通过Web框架(这里用Go标准库的net/http,也可以用Gin、Echo这类第三方框架)对外暴露接口。
一、准备Fabric Go SDK依赖
首先,你需要在你的Go项目里引入Fabric SDK的相关包。先初始化Go模块:
go mod init fabric-web-service
然后添加SDK依赖(注意要和你安装的Fabric版本对应,比如Fabric 2.4.x对应SDK的v2.4.x版本):
go get github.com/hyperledger/fabric-sdk-go/v2@v2.4.2
二、创建网络配置文件
要让SDK能连接到你的basic-network,需要一个config.yaml配置文件,里面定义了Peer节点、组织、证书路径等信息。你可以参考下面的示例,根据你的basic-network路径调整证书路径:
client: organization: Org1 credentialStore: path: "./tmp/state-store" cryptoStore: path: "./tmp/crypto-store" organizations: Org1: mspid: Org1MSP peers: - peer0.org1.example.com certificateAuthorities: - ca.org1.example.com peers: peer0.org1.example.com: url: grpcs://localhost:7051 tlsCACerts: path: "./fabric-samples/basic-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" orderers: orderer.example.com: url: grpcs://localhost:7050 tlsCACerts: path: "./fabric-samples/basic-network/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt"
提示:
./fabric-samples是你本地fabric-samples的路径,确保路径正确,否则SDK找不到证书会连接失败。
三、初始化Fabric SDK客户端
接下来编写Go代码初始化SDK和通道客户端,这是和区块链网络交互的基础:
package main import ( "fmt" "log" "net/http" "github.com/hyperledger/fabric-sdk-go/v2/pkg/client/channel" "github.com/hyperledger/fabric-sdk-go/v2/pkg/core/config" "github.com/hyperledger/fabric-sdk-go/v2/pkg/fabsdk" ) // 全局变量存储SDK和通道客户端 var ( sdk *fabsdk.FabricSDK chClient *channel.Client ) // 初始化函数,程序启动时执行 func init() { // 加载配置文件 configPath := "./config.yaml" cfgProvider := config.FromFile(configPath) // 创建Fabric SDK实例 var err error sdk, err = fabsdk.New(cfgProvider) if err != nil { log.Fatalf("创建SDK失败: %v", err) } // 创建通道客户端,连接到basic-network默认的mychannel通道 ctx := sdk.Context(fabsdk.WithUser("Admin"), fabsdk.WithOrg("Org1")) chClient, err = channel.New(ctx, channel.WithChannelID("mychannel")) if err != nil { log.Fatalf("创建通道客户端失败: %v", err) } }
四、编写Web接口处理函数
现在实现你需要的/queryUser接口,解析URL参数,调用链码的查询方法:
// queryUserHandler 处理用户余额查询请求 func queryUserHandler(w http.ResponseWriter, r *http.Request) { // 获取URL中的user参数 userID := r.URL.Query().Get("user") if userID == "" { http.Error(w, "缺少必填参数 'user'", http.StatusBadRequest) return } // 构造链码调用请求:调用example02的"query"方法,参数是用户ID req := channel.Request{ ChaincodeID: "mycc", // 这里是你安装链码时指定的ID,example02默认安装的ID是mycc Fcn: "query", Args: [][]byte{[]byte(userID)}, } // 调用链码查询 response, err := chClient.Query(req) if err != nil { http.Error(w, fmt.Sprintf("查询链码失败: %v", err), http.StatusInternalServerError) return } // 返回JSON格式的查询结果 w.Header().Set("Content-Type", "application/json") w.Write([]byte(fmt.Sprintf(`{"user": "%s", "balance": "%s"}`, userID, string(response.Payload)))) } func main() { // 注册路由 http.HandleFunc("/queryUser", queryUserHandler) // 启动Web服务,监听8080端口 log.Println("Web服务启动,监听端口 :8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
五、运行和测试
- 确保你的basic-network正在运行:如果之前启动过,检查容器状态
docker ps,如果没启动,运行fabric-samples/basic-network/start.sh。 - 安装依赖:
go mod tidy - 启动Web服务:
go run main.go - 测试接口:用curl或者浏览器访问
curl "http://localhost:8080/queryUser?user=abc"
如果一切正常,你会得到类似这样的返回:
{"user": "abc", "balance": "100"}
一些注意事项
- 链码ID要和你安装时的一致:example02链码安装时默认用的是
mycc,如果你的链码ID不同,要修改代码里的ChaincodeID字段。 - 证书路径要准确:如果你的fabric-samples不在当前项目的上级目录,要调整
config.yaml里的证书路径。 - 用户权限:用Admin用户是因为它默认有调用链码的权限,如果你想使用普通用户,需要先在CA上注册并登记用户。
- TLS连接:basic-network默认启用了TLS,所以配置里用的是
grpcs协议,如果你关闭了TLS,要改成grpc并去掉证书配置。
内容的提问来源于stack exchange,提问作者star24




