Closed jefft0 closed 1 year ago
Hey @jefft0,
Thank you for opening the issue.
As far as I know, the Gno execution environment fills out the Data
field of DeliverTx
when the call is finished:
https://github.com/gnolang/gno/blob/61520301d58a6ce0ace86fefefab2f29e66b7d06/gno.land/pkg/sdk/vm/handler.go#L63-L68
This is propagated out to the RPC layer, so you should be able to extract the response through the DeliverTx.ResponseBase.Data
object. Keep in mind that if you're doing this parsing through the RPC layer, this ResponseBase.Data
is base64 encoded, so you need to decode it on the client side.
I see that you are checking the CheckTx
field, and not the DeliverTx
field.
Try changing the print to this instead:
io.Println("DATA: ", len(bres.DeliverTx.ResponseBase.Data))
Since we don't have this documented anywhere (yet!), I'm going to provide some more context on how an RPC client could handle Realm calls below:
Example: If you want to call a method BertyFunc()
on a realm gno.land/r/berty
, you can send the following RPC request:
id: // random value
jsonrpc: "2.0"
method: "abci_query"
params: [
"vm/qeval",
"Z25vLmxhbmQvci9iZXJ0eQpCZXJ0eUZ1bmMoKQ==",
"0",
false
]
You might be wondering what Z25vLmxhbmQvci9iZXJ0eQpCZXJ0eUZ1bmMoKQ==
is.
It is the base64 encoding of the params for the vm/qeval
call. Specifically, it is the base64 encoding of (notice the newline):
gno.land/r/berty
BertyFunc()
As I mentioned above, since you're doing this request through the RPC layer, the response you get from the RPC query will be in fact an ABCI response object, that contains the field response.ResponseBase.Data
, which is base64 encoded.
Luckily, you don't have to handle this on your own -- we provide support for this exact functionality via the evaluateExpression
in gno-js-client
. Please note that this is for read-only methods (that don't modify the state).
I hope this answers several questions you might've had about this kind of Gno RPC shenanigans
Thanks! As you suggest, I changed the print statement to:
io.Println("DATA: ", string(bres.DeliverTx.ResponseBase.Data))
Now it prints "(20 gno.land/r/demo/boards.PostID)" (with no need to decode base64). This format is created by the TypedValue String method. Are there utility functions or a recommended way to "unmarshal" this into a useable object?
Thanks! As you suggest, I changed the print statement to:
io.Println("DATA: ", string(bres.DeliverTx.ResponseBase.Data))
Now it prints "(20 gno.land/r/demo/boards.PostID)" (with no need to decode base64). This format is created by the TypedValue String method.
If you're calling it directly from Go (using the Gno client code we have), you don't need to do base64 juggling
Are there utility functions or a recommended way to "unmarshal" this into a useable object?
Sadly we don't have a standard for parsing these values, you'd need to write a custom parser for them at the moment.
It's part of the bigger issue I'm trying to tackle in the near future, and that's having Realms / Packages have a sort of ABI (if you're familiar with how Solidity contracts get compiled into a parsable format). I've noted it here, in under the "ABI Support for Realms" section, and we have a meta issue by @moul: https://github.com/gnolang/gno/issues/925
Thanks again. Our immediate issue is solved since we can now get something for the return value of a function call. And it is a known issue that the client is currently at a loss for how to parse the value, but we can track the issues you mention. Closing this as answered.
I'm following the guide to call the board "CreateReply" realm function from the command line using a local gnoland node. The return value of this Gno function is the PostID . Indeed, in the node's ApplyBlock function I inserted a print statement:
As expected, the gnoland log output shows "Debug: abciResponses (20 gno.land/r/demo/boards.PostID)". Now, in the command-line client I insert the print statement:
The full output from calling "CreateReply" is:
The Data field is empty, but I expect it to have the return value of the realm function call. My question: When the client uses BroadcastTxCommit to do an RPC realm function call, should the the result Data field have the return value of the realm function call?