求助:Golang1.19编写的链码无法在Hyperledger Fabric1.4实例化
我用Golang 1.19编写了一个链码,希望在Hyperledger Fabric网络中运行,但实例化时出现以下错误:
Error: could not assemble transaction, err proposal response was not successful, error code 500, msg error starting container: error starting container: Failed to generate platform-specific docker build: Error returned from build: 1 "chaincode/input/src/github.com/chaincode/lattice/vendor/golang.org/x/net/http2/transport.go:19:2: cannot find package "io/fs" in any of:
/chaincode/input/src/github.com/chaincode/lattice/vendor/io/fs (vendor tree)
/opt/go/src/io/fs (from $GOROOT)
/chaincode/input/src/io/fs (from $GOPATH)
/opt/gopath/src/io/fs
"
尝试挂载Golang 1.19目录替换CLI容器中的Go环境后,运行byfn.sh up又出现新错误:
Error: error getting chaincode code mycc: error getting chaincode package bytes: Error obtaining imports: command <go list -f {{ join .Imports "\n"}} github.com/chaincode/chaincode_example02/go/>: failed with error: "exit status 1"
no required module provides package github.com/chaincode/chaincode_example02/go: go.mod file not found in current directory or any parent directory; see 'go help modules'!!!!!!!!!!!!!!! Chaincode installation on peer0.org1 has failed !!!!!!!!!!!!!!!!
========= ERROR !!! FAILED to execute End-2-End Scenario ===========ERROR !!!! Test failed
想了解如何解决该问题,是否必须使用相同版本的Golang重写链码?
第一个错误的根源
io/fs是Golang 1.16才引入的标准库,而Fabric默认的链码构建容器(如hyperledger/fabric-ccenv)内置的Go版本可能低于1.16,导致找不到该包。这是构建环境版本不匹配的问题,和链码本身无关。
具体解决步骤
匹配链码构建容器的Go版本
- 不要直接替换CLI容器的Go环境,而是使用对应Go 1.19版本的
fabric-ccenv镜像:- 若使用Fabric 2.5+,可查看官方
fabric-ccenv镜像标签,选择内置Go版本≥1.19的镜像(如hyperledger/fabric-ccenv:2.5.0); - 若官方镜像不满足,可自行构建
ccenv镜像:基于Go 1.19基础镜像,安装git、gcc等Fabric链码构建依赖。
- 若使用Fabric 2.5+,可查看官方
- 修改Fabric节点配置(如
core.yaml),将chaincode.builder字段设置为你选用的ccenv镜像地址。
- 不要直接替换CLI容器的Go环境,而是使用对应Go 1.19版本的
解决模块模式冲突(第二个错误)
替换CLI的Go环境后,默认示例链码chaincode_example02基于GOPATH模式开发,而Go 1.19默认启用模块模式,导致包查找失败,有两种解决方式:- 给示例链码添加模块配置:进入
chaincode_example02/go目录,执行go mod init github.com/chaincode/chaincode_example02/go,再执行go mod tidy生成go.mod和go.sum; - 在CLI容器中设置环境变量
GO111MODULE=off,强制切换回GOPATH模式,适配原有示例链码。
- 给示例链码添加模块配置:进入
无需重写链码
不需要重写链码,只要保证链码构建环境的Go版本≥1.16(适配io/fs包),同时调整Fabric构建流程适配对应环境即可。
额外注意事项
- 若链码包含
vendor目录,需确保依赖是基于Go 1.19编译的,或直接删除vendor目录,让构建容器自动拉取适配版本的依赖; - 自行构建
ccenv镜像时,要确保镜像内GOROOT、GOPATH等环境变量配置正确; - 运行
byfn.sh前,先清理旧环境:执行./byfn.sh down -v删除旧容器、镜像和数据卷。
内容的提问来源于stack exchange,提问作者npcxh

