2

I've been working on decoding called return values. I've discovered that there's a difference between the encoding using the automatically created getter function of a public state variable and a created getter function. To be specific, the decodeParameter web3.js function works with the created getter function returned encoded data, but not with the automatically created public state variable getter function. I can see that the encoding is done slightly differently in the encoded outputs.

This is the encoded called return value from the public state variable getter function. 0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000724ba66543d0493168fa1f67bde1b4251fc164b5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035465640000000000000000000000000000000000000000000000000000000000

This is the encoded called return value from the created getter function. 0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000724ba66543d0493168fa1f67bde1b4251fc164b5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035465640000000000000000000000000000000000000000000000000000000000

The data type being reing returned is a struct as defined below.

       "Candidate": {
            "name": 'string',
            "officeId": 'uint256',
            "candidateAddress": 'address',
            "arrayIndex": 'uint256',
        }

The specific information that I entered was: name Ted, candidateAddress 0x724ba66543d0493168fA1F67bde1b4251fC164b5, officeId 1, arrayIndex 0.

I can see these pieces of information in the encoded data in addition to where to start in the memory and the numbers of letters in the string. However, for some reason, one is encoded (i.e. arranged) in a way that is compatible with web3.eth.abi.decodeParameter and the other is not. Can anyone explain why?

I have this working using the created getter function, but I'm just looking for some deeper understanding of Solidity. I would appreciate any advice or comments. Cheers.

1
  • Are you using pragma experimental ABIEncoderV2; in your contract?
    – Jesbus
    Dec 16, 2020 at 16:23

1 Answer 1

2

Automatic getter functions of struct state variables will encode the struct data as if they were multiple return values, instead of returning one struct value. This is because before ABIEncoderV2, it was not possible to return a struct value.

In this example, the getter function for aaa encodes the data exactly like function bbb: as multiple return values. However, function ccc uses ABIEncoderV2 to encode one tuple value.

pragma solidity 0.7.5;

pragma experimental ABIEncoderV2;

contract Test
{
    struct Candidate
    {
        string name;
        uint256 officeId;
        address candidateAddress;
        uint256 arrayIndex;
    }
    constructor()
    {
        aaa.name = "aaaa";
        aaa.officeId = 5;
        aaa.candidateAddress = 0x6666666666666666666666666666666666666666;
        aaa.arrayIndex = 7;
    }
    Candidate public aaa;
    function bbb() external view returns (string memory name, uint256 officeId, address candidateAddress, uint256 arrayIndex)
    {
        return (aaa.name, aaa.officeId, aaa.candidateAddress, aaa.arrayIndex);
    }
    function ccc() external view returns (Candidate memory)
    {
        return aaa;
    }
}
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.