长安链2.3.0+的go合约虚拟机和2.3.0以下的不兼容,编译的方式也有差异,所以在ide上做了区分。
教程三会写一些,其他比较常用SDK方法的解释和使用方法
编写前的注意事项:
1、运行一条带有Doker_GoVM的链
2、建议直接用官方的在线IDE去写合约,因为写完可以直接测,缺点只是调试不方便。
3、如果自己拉环境在本地写合约,编译时注意编译环境,官方有提醒你去Linux下去编译。
4、如果你的链是2.3.+,使用编译器前,请先切换到2.3.+,以防不测
1、首先去新建一个合约工程
这里选择空白模板,其他模板好像是一些web3的规范模板
2、打开main.go文件(有一份示例合约)
/*
Copyright (C) BABEC. All rights reserved.
Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
SPDX-License-Identifier: Apache-2.0
*/
package main
import (
"encoding/json"
"fmt"
"log"
"strconv"
"chainmaker/pb/protogo"
"chainmaker/sandbox"
"chainmaker/sdk"
)
type FactContract struct {
}
// 存证对象
type Fact struct {
FileHash string
FileName string
Time int
}
// 新建存证对象
func NewFact(fileHash string, fileName string, time int) *Fact {
fact := &Fact{
FileHash: fileHash,
FileName: fileName,
Time: time,
}
return fact
}
func (f *FactContract) InitContract() protogo.Response {
return sdk.Success([]byte("Init contract success"))
}
func (f *FactContract) UpgradeContract() protogo.Response {
return sdk.Success([]byte("Upgrade contract success"))
}
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")
}
}
func (f *FactContract) Save() protogo.Response {
params := sdk.Instance.GetArgs()
// 获取参数
fileHash := string(params["file_hash"])
fileName := string(params["file_name"])
timeStr := string(params["time"])
time, err := strconv.Atoi(timeStr)
if err != nil {
msg := "time is [" + timeStr + "] not int"
sdk.Instance.Errorf(msg)
return sdk.Error(msg)
}
// 构建结构体
fact := NewFact(fileHash, fileName, time)
// 序列化
factBytes, err := json.Marshal(fact)
if err != nil {
return sdk.Error(fmt.Sprintf("marshal fact failed, err: %s", err))
}
// 发送事件
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)
// 返回结果
return sdk.Success([]byte(fact.FileName + fact.FileHash))
}
func (f *FactContract) FindByFileHash() protogo.Response {
// 获取参数
fileHash := string(sdk.Instance.GetArgs()["file_hash"])
// 查询结果
result, err := sdk.Instance.GetStateByte("fact_bytes", fileHash)
if err != nil {
return sdk.Error("failed to call get_state")
}
// 反序列化
var fact Fact
if err = json.Unmarshal(result, &fact); err != nil {
return sdk.Error(fmt.Sprintf("unmarshal fact failed, err: %s", err))
}
// 记录日志
sdk.Instance.Infof("[find_by_file_hash] fileHash=" + fact.FileHash)
sdk.Instance.Infof("[find_by_file_hash] fileName=" + fact.FileName)
// 返回结果
return sdk.Success(result)
}
func main() {
err := sandbox.