一、代码入口
代码入口包名必须为 main。
package main// sdk 代码中,有且仅有一个 main() 方法func main() { // main() 方法中,下面的代码为必须代码,不建议修改 main() 方法当中的代码 // 其中,TestContract 为用户实现合约的具体名称 err := shim.Start(new(TestContract)) if err != nil { log.Fatal(err) }}
二、存证合约示例
1. 存储文件哈希、文件名称、时间。
2. 通过文件哈希查询该条记录。
package mainimport ( "encoding/json" "log" "strconv" "chainmaker.org/chainmaker-contract-sdk-docker-go/pb/protogo" "chainmaker.org/chainmaker-contract-sdk-docker-go/shim")type FactContract struct {}// 存证对象type Fact struct { FileHash string `json:"FileHash"` FileName string `json:"FileName"` Time int32 `json:"time"`}// 新建存证对象func NewFact(FileHash string, FileName string, time int32) *Fact { fact := &Fact{ FileHash: FileHash, FileName: FileName, Time: time, } return fact}func (f *FactContract) InitContract(stub shim.CMStubInterface) protogo.Response { return shim.Success([]byte("Init Success"))}func (f *FactContract) InvokeContract(stub shim.CMStubInterface) protogo.Response { // 获取参数 method := string(stub.GetArgs()["method"]) switch method { case "save": return f.save(stub) case "findByFileHash": return f.findByFileHash(stub) default: return shim.Error("invalid method") }}func (f *FactContract) save(stub shim.CMStubInterface) protogo.Response { params := stub.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" stub.Log(msg) return shim.Error(msg) } // 构建结构体 fact := NewFact(fileHash, fileName, int32(time)) // 序列化 factBytes, _ := json.Marshal(fact) // 发送事件 stub.EmitEvent("topic_vx", []string{fact.FileHash, fact.FileName}) // 存储数据 err = stub.PutStateByte("fact_bytes", fact.FileHash, factBytes) if err != nil { return shim.Error("fail to save fact bytes") } // 记录日志 stub.Log("[save] FileHash=" + fact.FileHash) stub.Log("[save] FileName=" + fact.FileName) // 返回结果 return shim.Success([]byte(fact.FileName + fact.FileHash))}func (f *FactContract) findByFileHash(stub shim.CMStubInterface) protogo.Response { // 获取参数 FileHash := string(stub.GetArgs()["file_hash"]) // 查询结果 result, err := stub.GetStateByte("fact_bytes", FileHash) if err != nil { return shim.Error("failed to call get_state") } // 反序列化 var fact Fact _ = json.Unmarshal(result, &fact) // 记录日志 stub.Log("[find_by_file_hash] FileHash=" + fact.FileHash) stub.Log("[find_by_file_hash] FileName=" + fact.FileName) // 返回结果 return shim.Success(result)}func main() { err := shim.Start(new(FactContract)) if err != nil { log.Fatal(err) }}
三、存证合约代码说明
| 参数名称 | 描述 |
| InitContract | 合约的初始化函数,在合约部署时被调用,在本合约中为空。 |
| save | save 函数实现将文件相关信息记录到链上的功能。步骤如下:1. save 函数先通过 [参数处理]API 接口 GetArgs 函数拿到时间,文件哈希和文件名字等信息。2. 构造 Fact 结构,序列化为 byte 数据;且当序列化错误时调用 [其他辅助类]API 接口 Log 函数记录相应日志。3. 通过调用 [账本交互]API 接口 PutStateByte 函数将数据记录到链上。4. 最后通过调用 [其他辅助类]API 接口 Success 函数将操作结果记录到链上。 |
| findByFileHash | 通过文件哈希查询该条记录。步骤如下:1. findByFileHash 通过 [参数处理]API 接口 GetArgs 函数拿到要查找的文件的文件哈希。2. 通过 [账本交互]API 接口 GetStateByte 函数获取文件的信息;若失败则通过 [其他辅助类]API 接口 Error 函数将操作结果记录到链上,否则,通过 [其他辅助类]API 接口 Log 函数和 Success 函数记录相关日志和返回结果。 |