How is the output of a contract call encoded?

Hi I have a proxy contract A which delegates function execution to implementation contract B using the standard OpenZeppelin code:

assembly {
            calldatacopy(0, 0, calldatasize())


            let result := delegatecall(gas(), _implementation, 0, calldatasize(), 0, 0)

            // Copy the returned data.
            returndatacopy(0, 0, returndatasize())

            switch result
            // delegatecall returns 0 on error.
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }

when I tried to call a function getter for a result which is supposed to be [10, 100] I got the string 0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000064. What is this encoding and which library I can use to decode it? At first I thought it was RLP encoding but I checked with some RLP decoders and it did not check out. Thanks

I think you can use web3.js to do this, such as:

web3.eth.abi.encodeParameters(['address[]'], [a1,a2])
2 Likes

Thanks for the answer. Why do I need specify the types? I thought it is already encoded in the bytestring. Moreover when I tried to decode with ethers.js as follows ethers.utils.defaultAbiCoder.decode([`uint256`, `uint256`], output) I got [32,2] instead of [10,100].
Edit: I found the error, my mistake was in defining type. The output was supposed to be a dynamic array so instead of ['uint256', 'uint256'] it should have been ['uint256[]']

1 Like