智能合约通用合约设计
我们一般会在合约中定义结构体,然后序列化后存入 state 数据库中。一旦数据结构变化,就需要升级 chaincode。
下面我们只实现了 create, find, update, delete 四个方法,没有数据结构,用户自行提交 json 格式或者其他序列化后的字符串数据。
package main
import (
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
type SmartContract struct {} //默认的合约数据结构
//初始化合约Init方法
func (s *SmartContract) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success(nil)
}
//查询Query方法
func (s *SmartContract) Query(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success(nil)
}
//调用函数Invoke方法
func (s *SmartContract) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
//获取调用合约输入参数
function, args := stub.GetFunctionAndParameters()
//根据不同输入参数匹配不同方法
if function == "create" {
return s.create(stub, args)//args,指传入参数
} else if function == "find" {
return s.find(stub, args)
} else if function == "update" {
return s.update(stub, args)
} else if function == "delete" {
return s.delete(stub, args)
}
//如果出现错误即输出没有可用的函数参数
return shim.Error("Invalid Smart Contract function name.")
}
//创建、写入区块链数据库函数
func (s *SmartContract) create(stub shim.ChaincodeStubInterface, args []string) pb.Response {
//如果参数长度不为2报错
if len(args) != 2 {
return shim.Error("Incorrect number of arguments. Expecting 2")
}
//键值
_key := args[0]
_data := args[1]
//如果值为空报错
if(_data == ""){
return shim.Error("Incorrect string of data")
}
//读取键对应的值信息,检测是否已经存在该数据
existAsBytes,err := stub.GetState(_key)
if string(existAsBytes) != "" {
fmt.Println("Failed to create account, Duplicate key.")
return shim.Error("Failed to create account, Duplicate key.")
}
//把数据写入区块链中,键为string,值为byte[]数组
err = stub.PutState(_key, []byte(_data))
if err != nil {
return shim.Error(err.Error())
}
fmt.Printf("create %s %s \n", _key, string(_data))
返回写入的值数据信息
return shim.Success([]byte(_data))
}
//寻找区块链已经写入的数据
func (s *SmartContract) find(stub shim.ChaincodeStubInterface, args []string) pb.Response {
//如果参数不为1个报错
if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
//获取键数据,读取值数据
_key := args[0]
_data, err := stub.GetState(_key)
if err != nil {
return shim.Error(err.Error())
}
if string(_data) == "" {
return shim.Error("The key isn't exist.")
}else{
fmt.Printf("query %s %s \n", _key, string(_data))
}
//返回读取的值数据
return shim.Success(_data)
}
//进行数据更新
func (s *SmartContract) update(stub shim.ChaincodeStubInterface, args []string) pb.Response {
//如果长度不为2 报错
if len(args) != 2 {
return shim.Error("Incorrect number of arguments. Expecting 2")
}
//获取键值数据
_key := args[0]
_data := args[1]
//如果为空报错
if(_data == ""){
return shim.Error("Incorrect string of data")
}
//写入区块链
err := stub.PutState(_key, []byte(_data))
if err != nil {
return shim.Error(err.Error())
}else{
fmt.Printf("update %s %s \n", _key, string(_data))
}
//返回写入值数据
return shim.Success([]byte(_data))
}
// 删除相关区块链数据
func (t *SmartContract) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
//获得输入键数据
_key := args[0]
//在区块链中删除数据
err := stub.DelState(_key)
if err != nil {
return shim.Error("Failed to delete state")
}
return shim.Success(nil)
}
//函数开始
func main() {
//链码开始
err := shim.Start(new(SmartContract))
if err != nil {
fmt.Printf("Error creating new Smart Contract: %s", err)
}
}
进行测试:
进入cli容器:docker exec -it cli bash
安装链码:peer chaincode install -v 1.0 -n art -p chaincodedev/chaincode/art
实例化链码:peer chaincode instantiate -C myc -n art -v 1.0 -c '{"Args":["init",""]}'
测试调用:peer chaincode instantiate -C myc -n art -v 1.0 -c '{"Args":[]}'
希望大家关注我的微信公众号,有疑问可以后台留言。