弹珠资产管理 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())
}

results matching ""

    No results matching ""