开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情
本文已参与「开源摘星计划」,欢迎正在阅读的你加入。活动链接:github.com/weopenproje…
本章开个新坑,用 Golang 编写一个长安链智能合约。
先放官方文档。再次夸赞下官方,编写了非常详细的文档。
根据文档内对环境依赖的描述,追过上一个系列的伙伴们应该都已经没有问题了:
这里提到的 CMC 工具可以用搭建的管理台来替代,后续开发完后,我可以演示下。
这里拿官方的示例来分析下 Golang 智能合约开发:
先放下官方示例源码,这个智能合约展示了区块链的一个存证应用。即利用区块链的可信网络来保存证据、证明、合同等等,一旦数据上链,则具有可信属性,无法捏造、抵赖。
首先,这是智能合约的入口:
package
type FactContract struct { // 合约名称,使用结构体
}
func main() {
err := sandbox.Start(new(FactContract)) // 将合约名称结构体创建并传入
if err != nil {
sdk.Instance.Errorf(err.Error()) // sdk 是官方开发的 go 模块,用于开发 Golang 智能合约
}
}
开发 Golang 智能合约必须获取 sdk 模块:
go get chainmaker.org/chainmaker/contract-sdk-go/v2@v2.3.2
有的小伙伴会问,为啥要传入一个结构体啊?这是 Golang 里“类”的实现方法,不了解的可以搜索下“Go 面向对象编程”即可。没有接触过 Go 的,也可以看下我之前的系列文章😄(还在更新中...)。
根据约定,必须实现 FactContract 的下面这三个方法,DockerGo 虚拟机会根据需要调用相应的方法:
// InitContract install contract func
func (f *FactContract) InitContract() protogo.Response {
return sdk.Success([]byte("Init contract success"))
}
// UpgradeContract upgrade contract func
func (f *FactContract) UpgradeContract() protogo.Response {
return sdk.Success([]byte("Upgrade contract success"))
}
// InvokeContract the entry func of invoke contract func
func (f *FactContract) InvokeContract(method string) protogo.Response {
switch method {
// 存证合约有两个功能,保存“save”和查询“findByFileHash”
case "save":
return f.save()
case "findByFileHash":
return f.findByFileHash()
default:
return sdk.Error("invalid method")
}
}
接下来,看具体的智能合约实现(省略了一部分业务代码):
func (f *FactContract) save() protogo.Response {
params := sdk.Instance.GetArgs() // 调用 sdk 获取智能合约传参
...
// 发送事件,做个日志
sdk.Instance.EmitEvent("topic_vx", []string{fact.FileHash, fact.FileName})
// 存储数据到区块链上
err = sdk.Instance.PutStateByte("fact_bytes", fact.FileHash, factBytes)
if err != nil {
return sdk.Error("fail to save fact bytes")
}
// 记录日志
sdk.Instance.Infof("[save] fileHash=" + fact.FileHash)
sdk.Instance.Infof("[save] fileName=" + fact.FileName)
...
}
func (f *FactContract) findByFileHash() protogo.Response {
...
// 查询区块链上的数据
result, err := sdk.Instance.GetStateByte("fact_bytes", fileHash)
if err != nil {
return sdk.Error("failed to call get_state")
}
...
}
ok,到这里就完事了,很简单是吧。下一章,我们模仿存证智能合约,开发一个有趣且有意义的智能合约,拭目以待!