Reputation: 21
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
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
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