更新时间:2023-03-07 GMT+08:00
链代码示例(1.4风格)
如下是一个账户转账的链代码示例(1.4风格)仅供安装实例化,若您需要调测请参考Fabric官方示例中的链代码。
package main
import (
"fmt"
"strconv"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
type SimpleChaincode struct {
}
// 初始化数据状态,实例化/升级链代码时被自动调用
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
// println函数的输出信息会出现在链代码容器的日志中
fmt.Println("ex02 Init")
// 获取用户传递给调用链代码的所需参数
_, args := stub.GetFunctionAndParameters()
var A, B string // 两个账户
var Aval, Bval int // 两个账户的余额
var err error
// 检查合法性, 检查参数数量是否为4个, 如果不是, 则返回错误信息
if len(args) != 4 {
return shim.Error("Incorrect number of arguments. Expecting 4")
}
A = args[0] // 账户A用户名
Aval, err = strconv.Atoi(args[1]) // 账户A余额
if err != nil {
return shim.Error("Expecting integer value for asset holding")
}
B = args[2] // 账户B用户名
Bval, err = strconv.Atoi(args[3]) // 账户B余额
if err != nil {
return shim.Error("Expecting integer value for asset holding")
}
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
// 将账户A的状态写入账本中
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
if err != nil {
return shim.Error(err.Error())
}
// 将账户B的状态写入账本中
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
// 对账本数据进行操作时(query, invoke)被自动调用
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
fmt.Println("ex02 Invoke")
// 获取用户传递给调用链代码的函数名称及参数
function, args := stub.GetFunctionAndParameters()
// 对获取到的函数名称进行判断
if function == "invoke" {
// 调用 invoke 函数实现转账操作
return t.invoke(stub, args)
} else if function == "delete" {
// 调用 delete 函数实现账户注销
return t.delete(stub, args)
} else if function == "query" {
// 调用 query 实现账户查询操作
return t.query(stub, args)
}
// 传递的函数名出错,返回 shim.Error()
return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
}
// 账户间转钱
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var A, B string // 账户A和B
var Aval, Bval int // 账户余额
var X int // 转账金额
var err error
if len(args) != 3 {
return shim.Error("Incorrect number of arguments. Expecting 3")
}
A = args[0] // 账户A用户名
B = args[1] // 账户B用户名
// 从账本中获取A的余额
Avalbytes, err := stub.GetState(A)
if err != nil {
return shim.Error("Failed to get state")
}
if Avalbytes == nil {
return shim.Error("Entity not found")
}
Aval, _ = strconv.Atoi(string(Avalbytes))
// 从账本中获取B的余额
Bvalbytes, err := stub.GetState(B)
if err != nil {
return shim.Error("Failed to get state")
}
if Bvalbytes == nil {
return shim.Error("Entity not found")
}
Bval, _ = strconv.Atoi(string(Bvalbytes))
// X为转账金额
X, err = strconv.Atoi(args[2])
if err != nil {
return shim.Error("Invalid transaction amount, expecting a integer value")
}
// 转账
Aval = Aval - X
Bval = Bval + X
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
// 更新转账后账本中A余额
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
if err != nil {
return shim.Error(err.Error())
}
// 更新转账后账本中B余额
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
// 账户注销
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
A := args[0] // 账户用户名
// 从账本中删除该账户状态
err := stub.DelState(A)
if err != nil {
return shim.Error("Failed to delete state")
}
return shim.Success(nil)
}
// 账户查询
func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var A string
var err error
if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting name of the person to query")
}
A = args[0] // 账户用户名
// 从账本中获取该账户余额
Avalbytes, err := stub.GetState(A)
if err != nil {
jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
return shim.Error(jsonResp)
}
if Avalbytes == nil {
jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
return shim.Error(jsonResp)
}
jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
fmt.Printf("Query Response:%s\n", jsonResp)
// 返回转账金额
return shim.Success(Avalbytes)
}
func main() {
err := shim.Start(new(SimpleChaincode))
if err != nil {
fmt.Printf("Error starting Simple chaincode: %s", err)
}
}
父主题: Go语言链代码开发