When I make an eth_call to the Usdt smart contract on Eth MainNet, I get a 96-byte hex output.
0000000000000000000000000000000000000000000000000000000000000020 // What is this?
000000000000000000000000000000000000000000000000000000000000000a // Size of the output
5465746865722055534400000000000000000000000000000000000000000000 // Output ("Tether USD")
I understand that the 3rd 32 bytes contain the actual string output with right padding, and the 2nd 32 bytes contain the output size in bytes with left padding. What do the 1st 32 bytes contain?
{"jsonrpc":"2.0","method":"eth_call","params":[{"To":"0xdAC17F958D2ee523a2206206994597C13D831ec7","Data":"0x06fdde03"},"latest"],"id":1}
The first 32byte slot is an offset that points to the length slot, which is immediately followed by slot(s) containing the actual param value.
The offset is useful in cases when a function returns multiple dynamic-length arrays (a string
is represented as a dynamic-length byte array), like in this example:
pragma solidity ^0.8;
contract MyContract {
function foo() external pure returns (string memory, string memory) {
return ("Tether USD", "Ethereum");
}
}
Returned data:
# offset pointing to the length of the 1st param
0x0000000000000000000000000000000000000000000000000000000000000040
# offset pointing to the length of the 2nd param
0x0000000000000000000000000000000000000000000000000000000000000080
# 1st param length
0x000000000000000000000000000000000000000000000000000000000000000a
# followed by 1st param value
0x5465746865722055534400000000000000000000000000000000000000000000
# 2nd param length
0x0000000000000000000000000000000000000000000000000000000000000008
# followed by 2nd param value
0x457468657265756d000000000000000000000000000000000000000000000000
If you had a fixed-length param between those two, the returned data structure would look like this:
Docs: https://docs.soliditylang.org/en/latest/abi-spec.html#use-of-dynamic-types