[Ethereum] Understanding parameters of the STATICCALL opcode in Solidity inline assembly

assemblyevmsolidity

I am new to inline assembly. I have tried understanding different opcodes, and understood quite a bit, but still not be able to correlate them in context to STATICCALL opcode. Kindly help me understand what's happening here in this piece of code

function getUint(address addr, bytes memory data) internal view returns (uint result) {
    result = 0;

    assembly {
        let status := staticcall(16000, addr, add(data, 32), mload(data), 0, 0)

        // Success!
        if eq(status, 1) {
            if eq(returndatasize(), 32) {
                returndatacopy(0, 0, 32)
                result := mload(0)
            }
        }
    }
}

As far as I have understood from solidity assembly documentation,

STATICCALL: identical to call(g, a, 0, in, insize, out, outsize) but does not have v value and do not allow state modifications

How do the parameters in the above code represent in, insize, out and outsize?

Best Answer

From the call you have

staticcall(16000, addr, add(data, 32), mload(data), 0, 0)
  • 16000 is gas
  • addr target address
  • add(data, 32) input
  • mload(data) input size
  • 0 output
  • 0 output size

For bytes the first 32 bytes are the size and it follow the raw data. mload(data) read 32 bytes pointed by data (it returns the length of data). add(data, 32) it moves the pointer to the raw data skipping the size field.

Related Topic