Solidity – How to Calculate Output of abi.encode in Remix

remixsolidity

I'm still learning solidity but having some hard times while trying to understand how abi.encode works. I mean when i try to see it's output i see a long hex value. For example if i call this function :

function getHexTest() public pure returns(bytes memory){
        return abi.encode("1","2");
    }

I see this output on remix:

0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013200000000000000000000000000000000000000000000000000000000000000

So i couldn't understand how this works and how this value calculated exactly. Because it's not equal to these values hex ascii or any other thing. So question is how this is structured? I see different examples in documentation like encoding functions and arguments but to be able o fully understand i need to understand this first.

Best Answer

Incoming (parameters) or outcoming data package for a contract is formed according to the following principle:

  • Data types, which are limited on the length (address, uint32, bytes32), are transmitted with alignment to 32-byte word (64-hex numbers)
  • Data types, which are varying on the length (strings or arrays), are transmitted according to the following scheme:
    • In the object position in the list, we transmit the offset of the block and its data relatively to the beginning of the package (with alignment to 32-byte word)
    • A number of data items is transmitted in the first 32-byte word of the block
    • The data themselves are transmitted in the consequent 32-byte words

Let’s consider, for example, a block, where the following data are sent: address, string, uint32, address[] (a hexadecimal address relative to the beginning of the block is given in the beginning of every 32-byte sting for the convenience)

000:000000000000000000000000570f5d143ee469d12dc29bf8b3345fa5536476d9
020:0000000000000000000000000000000000000000000000000000000000000080
040:0000000000000000000000000000000000000000000000000000000000001234
060:00000000000000000000000000000000000000000000000000000000000000c0
080:0000000000000000000000000000000000000000000000000000000000000003
0a0:4e65770000000000000000000000000000000000000000000000000000000000 
0c0:0000000000000000000000000000000000000000000000000000000000000002 
0e0:000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
100:000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
  • In the 000 string, we send the following address: 0х570f5d143ee469d12dc29bf8b3345fa5536476d9.
  • In the 020 string, we send a link to the block, which describes a variable of a string type – 0x80 bytes from the beginning of block.
  • In the 040 string, we send an integer 0x1234.
  • In the 060 string, we send a link to a block, which describes an array address[] – 0xc0 bytes from the beginning of the block.
  • In the 080 string, we send a symbols counter via a variable of the type string – 3.
  • In the 0a0 string, we send symbols of the variable of the type string – a word New.
  • In the 0c0 sting, we send a counter of the array address[] items – 2.
  • In the 0e0 string, we send the first element of the address[] array - 0хaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.
  • In the 100 string, we send the second element of the address[] array - 0хbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.

In you keys we recieve 2 string variable:

0x000: 0000000000000000000000000000000000000000000000000000000000000040 (offset of 1st string)
0x020: 0000000000000000000000000000000000000000000000000000000000000080 (offset of 2nd string)
0x040: 0000000000000000000000000000000000000000000000000000000000000001 (size of 1st string)
0x060: 3100000000000000000000000000000000000000000000000000000000000000 (data of 1st string)
0x080: 0000000000000000000000000000000000000000000000000000000000000001 (size of 2nd string)
0x0a0: 3200000000000000000000000000000000000000000000000000000000000000 (data of 2nd string)
Related Topic