2. 使用Golang进行智能合约开发
读者对象:本章节主要描述使用Golang进行ChainMaker合约编写的方法,主要面向于使用Golang进行ChainMaker的合约开发的开发者。
2.1. 环境依赖
- 操作系统 目前仅支持在Linux系统下部署和运行 Docker VM,合约的编译也必须在Linux环境下执行。如果需要在其他系统环境下编译合约,请参考Golang的交叉编译修改编译命令。
- 软件依赖 推荐使用Goland 或 vscode等IDE编写和编译Golang合约。 编译后的合约需要经过7zip压缩形成最终的合约文件,7zip的安装请参看7zip官网
- 长安链环境准备
准备一条支持Docker_VM的长安链,以及长安链CMC工具,用于将写编写好的合约,部署到链上进行测试。相关安装教程请详见:
- 部署支持Docker_VM的长安链教程。
- 部署长安链CMC工具的教程。
2.2. 编写Golang合约
2.2.1. 通过go.mod引用合约SDK
ChainMaker官方Golang合约SDK支持通过go.mod的方式引用,可直接使用go get引用,示例如下:
代码语言:javascript复制$ go get chainmaker.org/chainmaker/contract-sdk-go/v2@v2.3.2
执行完成后,即可参考下文的编写合约注意事项,调用合约sdk的方法,编写合约。
2.2.2. 编写合约注意事项
- 代码入口包名必须为
main
- 代码入口 package main // sdk代码中,有且仅有一个main()方法 func main() { // main()方法中,下面的代码为必须代码,不建议修改main()方法当中的代码 // 其中,TestContract为用户实现合约的具体名称 err := sandbox.Start(new(FactContract)) if err != nil { log.Fatal(err) } }
- 合约必要代码 // 合约结构体,合约名称需要写入main()方法当中 type FactContract struct { } // 合约必须实现下面两个方法: // InitContract() protogo.Response // UpgradeContract() protogo.Response // InvokeContract(method string) protogo.Response // 用于合约的部署 // @return: 合约返回结果,包括Success和Error func (f *FactContract) InitContract() protogo.Response { return sdk.Success([]byte("Init contract success")) } // 用于合约的升级 // @return: 合约返回结果,包括Success和Error func (f *FactContract) UpgradeContract() protogo.Response { return sdk.Success([]byte("Upgrade contract success")) } // 用于合约的调用 // @param method: 交易请求调用的方法 // @return: 合约返回结果,包括Success和Error func (f *FactContract) InvokeContract(method string) protogo.Response { switch method { case "save": return f.save() case "findByFileHash": return f.findByFileHash() default: return sdk.Error("invalid method") } }
2.2.3. 合约SDK接口描述
长安链提供golang合约与链交互的相关接口,写合约时可直接导入包,并进行引用,具体信息可参考文章末尾”接口描述章节”。
2.2.4. 编译合约
当合约编写完成后,则需要编译合约,具体教程如下
2.2.4.1. 使用脚本编译合约
- 在合约工程中添加编译脚本build.sh搭建编译环境。 #!/bin/bash contractName=$1 if [[ ! -n $contractName ]] ;then echo "contractName is empty. use as: ./build.sh contractName" exit 1 fi go build -ldflags="-s -w" -o $contractName 7z a $contractName $contractName rm -f $contractName