sebi
sebi

Reputation: 21

Chaincode HLF store variables with additional info

i am using a hlf system based on chaincode to show how smart contracts could be created.

Now i am stuck with (in my mind) a very easy problem i guess.

I want to store a data objects content as key-value pair on the chains couchDb state database.

I am doing this with a docker request looking like this: COMMAND WRITE: docker exec -t Lane1_Zf4URs_cli peer chaincode invoke -o orderer.Zf4URs.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/Zf4URs.com/orderers/orderer.Zf4URs.com/msp/tlscacerts/tlsca.Zf4URs.com-cert.pem -C mychannel -n 9bc7cca8-1dcd-49b0-a25c-fb639a0403cf -c '{"Args":["set", "[D1]{P1}", "data4"]}'

So as you see my args are calling set method and store key="[Di]{P1}" value="data4" this is working fine with this "set" method.

func (s *SmartContract) set(stub shim.ChaincodeStubInterface, args []string) peer.Response {

if len(args) != 2 {

    return shim.Error("Incorrect arguments. Expecting a key and a value")

}



err := stub.PutState(args[0], []byte(args[1]))

if err != nil {

    return shim.Error("Failed to set asset: " + string(args[0]))

}

return shim.Success([]byte(args[1]))

// return args[1]

}

Now when looking at state dB this is the stored result:

{ "_id": "[D1]{P1}", "_rev": "2-a74269cadec50f97d34d165d60235e34", "~version": "8:0", "_attachments": { "valueBytes": { "content_type": "application/octet-stream", "revpos": 2, "digest": "md5-2cRbxPYpSEbldj1mVovx8Q==", "length": 5, "stub": true } } }

Now what i want to have is to store an additional value on this state db request. Beside of "_id" (key) i want to have another field called "_executor" which should have a value "{P1}"

Should look like this:

{ "_id": "[D1]{P1}", "_rev": "2-a74269cadec50f97d34d165d60235e34", "_executor": "{P1}", "~version": "8:0", "_attachments": { "valueBytes": { "content_type": "application/octet-stream", "revpos": 2, "digest": "md5-2cRbxPYpSEbldj1mVovx8Q==", "length": 5, "stub": true } } }

How can i do that? What do i have to change on the docker request or on the set method? Is this even possible?

Many thanks for help

Upvotes: 0

Views: 62

Answers (2)

sebi
sebi

Reputation: 21

I have updated my code. I tried to use a struct and store this.

`type DataObject struct {
Name string
Executor string
Data []byte} func (s *SmartContract) set(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 2 {
    return shim.Error("Incorrect arguments. Expecting a key and a value")
}

p := DataObject{
    Name: args[0],
    Executor: "p1",
    Data: []byte(args[1]),
}
str, err2 := json.Marshal(p)

if err2 != nil {
    fmt.Println(err2)
}

fmt.Println(string(str)) 

if(args[1] == "data4"){
    err := stub.PutState(args[0], str)

    if err != nil {
        return shim.Error("Failed to set asset: " + string(args[0]))
    }
    return shim.Success(str)
} else {
    err := stub.PutState(args[0], []byte(args[1]))
    if err != nil {
        return shim.Error("Failed to set asset: " + string(args[0]))
    }

    return shim.Success([]byte(args[1]))
}}`

Now i can store executor but my data variable gets not stored as before. I need the digest so as before it should be _attachments: [valueBytes: ....digest:md5-xxx].

It looks like this: couchDb-doc

{ "_id": "[D1]{P1}", "_rev": "1-69be87268fs88s788668f8s766fnkushof7", "Data": "ZGF0YTQ=", "Executor": "P1", "Name": "[D1]{P1}", "_version": "3:0" }

Upvotes: 0

Sabina Orazem
Sabina Orazem

Reputation: 487

This should work! You have no constrains on the second argument (args[1]) in your smart contract. And since this is a string it's stored in one column and hence doesn't depend on the table structure.

Upvotes: 0

Related Questions