2

I write a small test script to see how callData works in remix. The script is listed below:

contract Assem {
    uint256 public count;
    function callData() public pure returns(bytes4) {
        assembly {
            calldatacopy(0x0, 0, 4)
            return (0x0, 4)
        }
    }
}

The code throws the error:

error: Failed to decode output: Error: data out-of-bounds (length=4, offset=32, code=BUFFER_OVERRUN, version=abi/5.1.2)

I make a change to return(0x0,32) and it seems working normally.

contract Assem {
    uint256 public count;
    function callData() public pure returns(bytes4) {
        assembly {
            calldatacopy(0x0, 0, 4)
            return (0x0, 32)
        }
    }
}

I am not sure why it is working in this way. I believe I only copy 0 ~ 4 bytes from callData, How could it become 32 bytes?

0

Remix expects the contract to follow ABI specs. In one part the specs says all data that is less than 32 bytes has to be padded to 32 bytes.

The contract is effectively returning 4 bytes and remix doesn't know what to do with just 4 bytes since it expecting 32 bytes. It will trim those 32 bytes by removing the padding.

3
  • Ismael, Thanks for your reply. I understand your point, but it is possible to return 4bytes data normally if I do not use assembly return. Are you saying Remix treats normal return and assembly return in a different way?
    – Eric Lee
    Jul 12 at 0:23
  • @EricLee It is not remix, it is the compiler, the return data has to follow the Solidity ABI, it will padd bytes4 to 32 bytes. When the contract return from assembly the compiler doesn't add the padding and remix complains because it expects a bytes4 padded to 32 bytes. Even when returning a bool the return data will be padded to 32 bytes.
    – Ismael
    Jul 12 at 4:08
  • 1
    Ismael, Thanks for the detailed explaination. I am clear.
    – Eric Lee
    Jul 14 at 4:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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