I want to understand how to encode the following arrays in Solidity.
Dynamic Arrays
For example, the following:
function getDynamicUintArray() public pure returns (uint[] memory) {
uint[] memory array = new uint[](3);
array[0] = 1;
array[1] = 2;
array[2] = 3;
return array;
}
Following the formal specification in documentation: We will proceed as follows:
enc(array) = enc(len(array)) enc(array[0]) enc(array[1]) enc([array[2])
This would result in the following:
0000000000000000000000000000000000000000000000000000000000000003
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000003
The problem is when I do this for a contract I deployed on Rinkeby, and execute the following RPC call:
curl <rinkeby_endpoint> -X POST --data '{"jsonrpc":"2.0", "method":"eth_call", "params":[{"from": "<send_address>", "to": "0xaD2bbEeF0A1FCa287d7a1d6cFa925E8C79cC7aC0", "data": "0x421fc531"}, "latest"], "id":4}'
I get the following result:
{"jsonrpc":"2.0","id":4,"result":"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"}
Which has an extra 0000000000000000000000000000000000000000000000000000000000000020
at the beginning. What is exactly that extra ?
Structs Array
Also, when encoding structs. The following example:
struct Foo {
string id;
string name;
}
When I run the following function:
function getMultipleFoo() public pure returns (Foo[] memory) {
Foo[3] multipleFoo;
Foo memory _foo = Foo("id", "name");
multipleFoo[0] = _foo;
multipleFoo[1] = _foo;
multipleFoo[2] = _foo;
return multipleFoo;
}
I should be receiving something like:
0000000000000000000000000000000000000000000000000000000000000060 == offset of first struct
0000000000000000000000000000000000000000000000000000000000000120 == offset of second struct
00000000000000000000000000000000000000000000000000000000000001e0 == offset of third struct
0000000000000000000000000000000000000000000000000000000000000040 == offset of first struct string
0000000000000000000000000000000000000000000000000000000000000080 == offset of second struct string
0000000000000000000000000000000000000000000000000000000000000002 == first string length
6964000000000000000000000000000000000000000000000000000000000000 == "id" hex representation
0000000000000000000000000000000000000000000000000000000000000004 == second string length
6e616d6500000000000000000000000000000000000000000000000000000000 == "name" hex representation
0000000000000000000000000000000000000000000000000000000000000040 == offset of first struct string
0000000000000000000000000000000000000000000000000000000000000080 == offset of second struct string
0000000000000000000000000000000000000000000000000000000000000002 == first string length
6964000000000000000000000000000000000000000000000000000000000000 == "id" hex representation
0000000000000000000000000000000000000000000000000000000000000004 == second string length
6e616d6500000000000000000000000000000000000000000000000000000000 == "name" hex representation
0000000000000000000000000000000000000000000000000000000000000040 == offset of first struct string
0000000000000000000000000000000000000000000000000000000000000080 == offset of second struct string
0000000000000000000000000000000000000000000000000000000000000002 == first string length
6964000000000000000000000000000000000000000000000000000000000000 == "id" hex representation
0000000000000000000000000000000000000000000000000000000000000004 == second string length
6e616d6500000000000000000000000000000000000000000000000000000000 == "name" hex representation
However, when I get the return value of that function call, I get an extra 0000000000000000000000000000000000000000000000000000000000000020
at the beginning like in the first case.