0

Why this does not work?

pragma solidity ^0.8.0;

contract DecodeTest {

    function test() external pure returns (string memory s, uint n1, int n2, bool b) {

        string memory str = "testing";
        uint  number1 = 123;
        int  number2 = -321;
        bool  boolean = true;

        bytes memory data = abi.encode(str, number1, number2, boolean);

        (s, data) = abi.decode(data, (string, bytes));
        (n1, data) = abi.decode(data, (uint, bytes));
        (n2, data) = abi.decode(data, (int, bytes));
        (b, data) = abi.decode(data, (bool, bytes));

    }

}

I was expecting that abi.decode would return the remaining bytes on each call.

It is generating an overflow on the second decode call.

Is there another way to decode in steps?

My real use case is to decode arbitrary data returned from external calls, in which the called function can return different number of arguments and different ordering of types

1
  • The function abi.encode/abi.decode use the Contract ABI specification. The way it is used in the contract isn't supported because you are mixing fixed size variables (uint) with dynamic variables (string, bytes) and that the encoding will not align as it is expected.
    – Ismael
    Commented Jul 24, 2022 at 18:04

1 Answer 1

1

You can't decode data twice that isn't in the correct format. You could pull out the data manually by reading memory directly, but a more practical approach is to encode it multiple times.

    function test() public {
        string memory str = "testing";
        uint256 number1 = 123;
        int256 number2 = -321;
        bool boolean = true;

        bytes memory encoded;

        encoded = abi.encode(str, number1);
        encoded = abi.encode(encoded, number2);
        encoded = abi.encode(encoded, boolean);

        bytes memory decoded;

        (decoded, boolean) = abi.decode(encoded, (bytes, bool));
        (decoded, number2) = abi.decode(decoded, (bytes, int256));
        (str, number1) = abi.decode(decoded, (string, uint256));
    }

Your Answer

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

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