长安链 Golang 智能合约开发实战01

941 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情

本文已参与「开源摘星计划」,欢迎正在阅读的你加入。活动链接:github.com/weopenproje…

本章开个新坑,用 Golang 编写一个长安链智能合约。

先放官方文档。再次夸赞下官方,编写了非常详细的文档。

根据文档内对环境依赖的描述,追过上一个系列的伙伴们应该都已经没有问题了:

image.png

这里提到的 CMC 工具可以用搭建的管理台来替代,后续开发完后,我可以演示下。

这里拿官方的示例来分析下 Golang 智能合约开发:

image.png

先放下官方示例源码,这个智能合约展示了区块链的一个存证应用。即利用区块链的可信网络来保存证据、证明、合同等等,一旦数据上链,则具有可信属性,无法捏造、抵赖。

首先,这是智能合约的入口:

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,到这里就完事了,很简单是吧。下一章,我们模仿存证智能合约,开发一个有趣且有意义的智能合约,拭目以待!