弹珠资产管理 chaincode 开发
主要开发功能
- 创建一个弹珠信息
- 从账本中读取一个弹珠信息
- 删除一个弹珠信息
- 更改一个弹珠的拥有者
- 返回所有名称在指定字典范围内的弹珠信息
- 返回指定拥有者拥有的所有的弹珠的信息
- 返回一个弹珠的所有历史信息
chaincode 代码实现
创建一个弹珠信息
创建弹珠的主要操作:
- 根据marbleName查询弹珠是否被创建
- 如果没有创建,将marble对象转为json对象,将marble写入到账本中
func(t *MarblesChaincode) initMarble(stub shim.ChaincodeStubInterface, args []string) peer.Response {
fmt.Println("initMarble start")
marbleName := args[0]
color := args[1]
size, err := strconv.Atoi(args[2])
if err != nil {
return shim.Error("size 必须是数字")
}
owner := args[3]
// 首先判断 marbleName 是不是已经存在
marbleAsBytes , err := stub.GetState(marbleName)
if err != nil {
return shim.Error ("获取marble失败:"+err.Error())
}else if marbleAsBytes != nil {
fmt.Printf("%s marble 已经存在!",marbleName)
return shim.Error("marble 已经存在!")
}
objectType := "marble"
marble := &marble{objectType,marbleName,color,size,owner}
marbleJsonAsBytes,err := json.Marshal(marble)
if err != nil {
return shim.Error(err.Error())
}
fmt.Printf("marbleJsonAsBytes %v: \n",string(marbleJsonAsBytes))
err = stub.PutState(marbleName,marbleJsonAsBytes)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
从账本中读取一个弹珠信息
查询弹珠信息主要操作:
- 通过 GetState 获取相应的弹珠信息
func (t *MarblesChaincode) readMarble (stub shim.ChaincodeStubInterface, args []string) peer.Response {
fmt.Println("readMarble start")
var name, jsonResp string
name = args[0]
marbleAsBytes,err := stub.GetState(name)
if err != nil {
jsonResp = "{\"error\": \"获取数据失败!\"}"
return shim.Error(jsonResp)
} else if marbleAsBytes == nil {
jsonResp = "{\"error\": \"marble 不存在!\"}"
return shim.Error(jsonResp)
}
return shim.Success(marbleAsBytes)
}
删除一个弹珠信息
删除一个弹珠信息主要操作:
- 查询弹珠是否存在
- 根据 marbleName 删除相应弹珠
func (t *MarblesChaincode) deleteMarble (stub shim.ChaincodeStubInterface, args []string) peer.Response {
fmt.Println("deleteMarble start")
var marblename string
marblename = args[0]
marbleAsBytes , err := stub.GetState(marblename)
if err != nil {
return shim.Error("获取marble信息失败!"+err.Error())
} else if marbleAsBytes == nil {
return shim.Error("marble 不存在!")
}
err = stub.DelState(marblename)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
更改一个弹珠的拥有者
主要操作:
- 根据 marbleName 查询 marble详情
- 修改 marble的拥有者
- 写入到账本中
func (t *MarblesChaincode) transferMarble (stub shim.ChaincodeStubInterface, args []string) peer.Response {
marbleName := args[0]
newOwner := args[1]
fmt.Println("start transferMarble ", marbleName, newOwner)
marbleAsBytes, err := stub.GetState(marbleName)
if err != nil {
return shim.Error("获取marble信息失败!")
} else if marbleAsBytes == nil {
return shim.Error("marble 不存在!")
}
marbleToTransfer := marble{}
err = json.Unmarshal(marbleAsBytes,&marbleToTransfer)
if err != nil {
return shim.Error(err.Error())
}
marbleToTransfer.Owner = newOwner
marbleJsonToTransfer , err := json.Marshal(marbleToTransfer)
err = stub.PutState(marbleName,marbleJsonToTransfer)
if err != nil {
return shim.Error(err.Error())
}
fmt.Println("end transferMarble ")
return shim.Success(nil)
}
返回所有名称在指定字典范围内的弹珠信息
- 通过起始key和终止key 获取到指定弹珠信息
- 通过迭代将弹珠信息转为JSON数组
func (t *MarblesChaincode) getMarblesByRange( stub shim.ChaincodeStubInterface, args []string) peer.Response{
fmt.Println("start getMarblesByRange")
startKey := args[0]
endKey := args[1]
resultIterator, err := stub.GetStateByRange(startKey,endKey)
if err != nil {
return shim.Error(err.Error())
}
defer resultIterator.Close()
//迭代resultIterator
var buffer bytes.Buffer
buffer.WriteString("[")
isWrited := false
for resultIterator.HasNext() {
queryResponse, err := resultIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
if isWrited == true {
buffer.WriteString(",")
}
buffer.WriteString("{\"key\":")
buffer.WriteString("\"")
buffer.WriteString(queryResponse.Key)
buffer.WriteString("\",\"record\":")
buffer.WriteString(string(queryResponse.Value))
buffer.WriteString("}")
}
buffer.WriteString("]")
fmt.Printf("getMarblesByRange result: \n%s\n",buffer.String())
fmt.Println("end getMarblesByRange")
return shim.Success(buffer.Bytes())
}
运行结果:
[{"key":"marble2","record":{"docType":"marble","name":"marble2","color":"red","size":50,"owner":"jerry"}}{"key":"marble3","record":{"docType":"marble","name":"marble3","color":"blue","size":70,"owner":"tom"}}]
返回指定拥有者拥有的所有的大理石的信息
该查询为富查询,需要支持富查询的数据库(如CouchDB)
func (t *MarblesChaincode) queryMarblesByOwner(stub shim.ChaincodeStubInterface,args []string) peer.Response{
fmt.Println("start queryMarblesByOwner")
owner := args[0]
queryString := fmt.Sprintf("{\"selector\":{\"docType\":\"marble\",\"owner\":\"%s\"}}",owner)
fmt.Println(queryString)
resultIterator, err := stub.GetQueryResult(queryString)
if err != nil {
return shim.Error(err.Error())
}
defer resultIterator.Close()
//迭代resultIterator
var buffer bytes.Buffer
buffer.WriteString("[")
isWrited := false
for resultIterator.HasNext() {
queryResponse, err := resultIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
if isWrited == true {
buffer.WriteString(",")
}
buffer.WriteString("{\"key\":")
buffer.WriteString("\"")
buffer.WriteString(queryResponse.Key)
buffer.WriteString("\",\"record\":")
buffer.WriteString(string(queryResponse.Value))
buffer.WriteString("}")
}
buffer.WriteString("]")
fmt.Printf("queryMarblesByOwner result: \n%s\n",buffer.String())
fmt.Println("end queryMarblesByOwner")
return shim.Success(buffer.Bytes())
}
返回一个大理石的所有历史信息
- GetHistoryForKey 获取相应的历史信息
func (t *MarblesChaincode) getHistoryForMarble(stub shim.ChaincodeStubInterface,args []string) peer.Response{
fmt.Println("start getHistoryForMarble")
marbleName := args[0]
fmt.Println("marbleName: ",marbleName)
resultIterator,err := stub.GetHistoryForKey(marbleName)
if err != nil {
return shim.Error(err.Error())
}
defer resultIterator.Close()
//迭代resultIterator
var buffer bytes.Buffer
buffer.WriteString("[")
isWrited := false
for resultIterator.HasNext() {
queryResponse, err := resultIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
if isWrited == true {
buffer.WriteString(",")
}
buffer.WriteString("{\"TxId\":")
buffer.WriteString("\"")
buffer.WriteString(queryResponse.TxId)
buffer.WriteString("\"")
buffer.WriteString(",\"Value\":")
if queryResponse.IsDelete {
buffer.WriteString("null")
}else{
buffer.WriteString(string(queryResponse.Value))
}
buffer.WriteString(",\"Timestamp\": ")
buffer.WriteString("\"")
buffer.WriteString(time.Unix(queryResponse.Timestamp.Seconds,int64(queryResponse.Timestamp.Nanos)).String())
buffer.WriteString("\"")
buffer.WriteString(",\"isDelete\":")
buffer.WriteString("\"")
buffer.WriteString(strconv.FormatBool(queryResponse.IsDelete))
buffer.WriteString("\"")
buffer.WriteString("}")
isWrited = true
}
buffer.WriteString("]")
fmt.Printf("getHistoryForMarble result \n%s\n",buffer.String())
fmt.Println("end getHistoryForMarble")
return shim.Success(buffer.Bytes())
}