本来不会GO,最近突击学了些GO的基础,就开始搞chaincode了。
首先给大家推荐一个非常好的Hyperldeger Fabric项目 marble:https://github.com/ibm-blockchain/marbles/
这次的项目,有很多地方借鉴了这个marble。
GO的包的引入
package main
import (
//"bytes"
"encoding/json"
"fmt"
"strconv"
//"strings"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
"time"
)
这些是经常用的包
Main
main是入口
// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}
// ===================================================================================
// Main
// ===================================================================================
func main() {
err := shim.Start(new(SimpleChaincode))
if err != nil {
fmt.Printf("Error starting Simple chaincode: %s", err)
}
}
Init
chaincode 包含一个Init和一个Invoke函数。
Init是初始化的地方,还需要注意以后版本升级时能够通用
// Init initializes chaincode
// ===========================
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success(nil)
}
Invoke
所有的调用都进入到这里,然后分发出去。
// Invoke - Our entry point
// ========================================
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
function, args := stub.GetFunctionAndParameters()
fmt.Println("invoke is running " + function)
// Handle different functions
if function == "initProvider" { // create Provider
return t.initProvider(stub, args)
} else if function == "initBeneficiary" { // create beneficiary
return t.initBeneficiary(stub, args)
}
fmt.Println("invoke did not find func: " + function) //error
return shim.Error("Received unknown function ")
}
数据定义
强烈建议,每个数据都增加一个额外的ObjectType字段,以便更好的查询(rich query)
ObjectType总是被保存为数据名称(Provider)
如果是复杂字段,则需要将首字母大写,不然序列化的时候回丢失(好像是被认为private)
type Provider struct {
ObjectType string `json:"ObjectType"` //docType is used to distinguish the various types of objects in state database
Name string `json:"Name"`
Id string `json:"Id"`
Eligibility bool `json:"Eligibility"`
}
关键语法
//序列化
providerJSONasBytes, err := json.Marshal(provider)
// 指定Id,保存
err = stub.PutState(id, providerJSONasBytes)
//根据Id查询
providerAsBytes, err := stub.GetState(id)
//反序列化
err = json.Unmarshal(providerAsBytes, &provider) //unmarshal it aka JSON.parse()
Selector查询
queryString := fmt.Sprintf("{"selector":{"ObjectType":"ServiceTransaction","ServiceCode":"%s","RideId":"%s"}}", "T01", ride.Id)
resultsIterator, err := stub.GetQueryResult(queryString)
// loop all results
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
由于一些原因不能上传代码。如果有需要,请留下联系方式。