0

I am trying to perform a query on a chaincode(cc02) from another chaincode (cc01), both residing on the same channel. When I try invoking the query function by calling stub.invokeChaincode(...), the command is returning a [Object object] instead of the result of the query. Can someone please tell what the mistake in this is?

More details

Minimal version of the querying function in cc01 reads:

async queryOtherContract(stub, args) {
    let chaincodeName = args[0]; //cc02
    let fcn = args[1];           //query
    let fcnArgs = args[2];       //key
    let channel = args[3];       //defaultchannel
    let queryResponse = await stub.invokeChaincode(chaincodeName, [fcn, fcnArgs], channel);
    console.log('Query response: ', JSON.stringify(queryResponse));
}

Output:

Query response: {"status":200,"message":"","payload":{"buffer":{"type":"Buffer","data":[8,6...108]},"offset":9,"markedOffset":-1,"limit":59,"littleEndian":true,"noAssert":false}}

The payload Buffer decodes to [Object object]

The queried function from cc02 is as follows:

async query(stub, args) {
    let key = args[0]; //key
    let valueAsBytes = await stub.getState(key);
    let valString = valueAsBytes.toString('utf8');
    console.log('Value String: ', valString);
    return shim.success(Buffer.from(valString));
}

Output: Value String: Value001

I have tried different variations as well including sending valueAsBytes directly as well as returning valString directly instead of wrapping it in the shim function. What am I doing wrong in this?

KBhokray
  • 117
  • 1
  • 10

2 Answers2

1

It is returning a buffer so you need to do the following:

Replace the following line:

return shim.success(valString);

with:

return shim.success(Buffer.from(valString));

The first chaincode (cc01) gets an object response and not a string.

Faran
  • 134
  • 5
  • My bad. I am actually returning Buffer.from(valString), edited the question accordingly. I was deserializing just to print it to the console and have tried sending valAsBytes as well. Sending valAsBytes, too, gives [Object object] – KBhokray Apr 17 '18 at 13:03
  • Can you try the following: console.log('Query response: ', Buffer.from(JSON.parse(queryResponse.payload.buffer).data).toString('utf8'); – Faran Apr 17 '18 at 13:48
  • I've managed to solve it. Turns out the mistake was in the payload decoding part where I was expecting the callee chaincode to give a string when it was actually receiving an object. Quite an embarrassing mistake. If you just edit your answer mentioning that the cc01 gets an object response and not a string, I'll accept it. Thanks! – KBhokray Apr 18 '18 at 04:41
  • @KBhokray could you elaborate? I am facing the exact same issue right now. (what's your code to read the received object?) – Itération 122442 Mar 22 '19 at 10:18
  • @Andromelus It's been a while since I've worked on the project, I've moved on to another platform now. I'm not able to find the part even in my VCS. FWIW, this is the closest I've got: CC: async getUserAccount(stub, args) { let usrAsBytes = await stub.getState(args[0]) let usrStr = usrAsBytes.toString('utf8') var usr = JSON.parse(usrStr) return shim.success(Buffer.from(JSON.stringify(usr))) } Client: let usr = await channel.queryByChaincode(request) var usrStr = usr[0].toString('utf8') var usrJson = JSON.parse(usrStr) – KBhokray Mar 22 '19 at 18:21
0

I encountered a similar issue while calling chaincode invoke query from another chaincode in a network with only a single channel. It seems that calls to invokeChaincode:

var response = stub.invokeChaincode("MyChaincode", ["query", key])

Return not just the payload of the query but also modify the query by appending the transaction id and the channel along with the read/write set. (This is with v1.2 packages and network.)

response.payload.toString() was returning for me:

�{"carId":"CAR_0001"}"@48147a5a84e591671363053e58e4c56fe5d3e42c4adce1ecb2ce92f9922fd5b6:mychannel

Where the transaction id for the query is: 48147a5a84e591671363053e58e4c56fe5d3e42c4adce1ecb2ce92f9922fd5b6

and my channel name: mychannel. Not really sure what � represents.

Even though the payload passed to shim.success(payload) I confirmed to be:

{"carId":"CAR_0001"}

This was incredibly confusing, since I do not know why it modifies the actual payload string. My workaround was to extract my json string with indexOf and lastIndexOf bracket from the response.

According to the docs:

If the called chaincode is on the same channel, it simply adds the called chaincode read set and write set to the calling transaction.

But the documentation does not mention modifying the payload or anything about the transaction id or channel name.

Hope this helps with querying chaincode from other chaincode on the same channel. Please correct me if I have incorrectly said something.