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:


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.

1 Answer 1


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)

  • 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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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