I have a view call in my Solidity code that looks like this:
function call1 (address[] calldata targets) external view returns(Return[] memory returnData)
And the struct from the array which is returned looks like this:
struct Return {
bool success;
address addr;
bytes data;
}
My goal is to decode the function call results of this function in Golang. So far I could log the results partially with this code:
res, err := client.CallContract(context.Background(), callMsg, nil)
outputDataList := make([]interface{}, 10)
outputDataList, err = contractABI.Unpack("call1", res)
fmt.Println(outputDataList[0].(interface{}))
I could log the bool
and address
from the struct, however the bytes variable is still not encoded.
[{true 0x8840c6252e2e86e545defb6da98b2a0e26d8c1ba[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 75 122 0 63 109 85 204 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 215 247 135 154 188 2 164 101 11 198 216 164 41 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100 139 110 44]} {true 0x8840c6252e2e86e545defb6da98b2a0e26d8c1ba[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 75 122 0 63 109 85 204 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 215 247 135 154 188 2 164 101 11 198 216 164 41 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100 139 110 44]}]
My question is that how should I continue the decode process of this? I would like to have the results in an array of structs that have the same structure as the Solidity struct. What would be the most elegant way to do it? I am also no sure that using an array (outputDataList
) is the best option or another solution should be used.
Best Answer
In Golang, the Go Ethereum library provides the
abi
package which has methods to unpack the transaction data. However, because thebytes
data type in Solidity is dynamic, it needs to be decoded differently than fixed-size types likebool
andaddress
.You are currently using the
Unpack
method which can handle thebool
andaddress
types but is not handling thebytes
type correctly. To handle the bytes type, you would need to manually parse it.Here's an example:
This code creates a Go struct that mirrors the Solidity struct and then unpacks the values into it. The
bytes
data type is converted to a byte slice ([]byte
) in Go. Note that this is just a basic example, and you might need to modify it based on your specific needs, especially the part that deals with the conversion of data types.Please replace
contractABI
with the ABI of your contract and ensure that the function and field names match your contract's. If theUnpackIntoInterface
function doesn't work as expected, you might need to do more manual decoding, especially for thebytes
field. You can reference the Solidity ABI specification for how the data is encoded and decoded.