Why are Encoders used in Solidity?

Harvesto Orlando
Coinmonks
4 min readApr 17, 2023

--

So, I have been learning Solidity — mainly focused on syntax and functions — and recently discovered encoders. Have you ever wondered how Ethereum transmits data and function calls? That’s what encoders are for — encoding/decoding function calls and data in a standard format.

I searched online WHY encoders are used in Solidity, like what are some of the reasons or conditions for use? What difference exists in writing Solidity code without encoding and compiling it to ABI and bytecode? My search only yielded explanations of their functionality… Until I found an answer that makes sense. In this article, I will take you on a discovery journey, exploring why ABI encoders are an essential tool for Solidity developers.

Encoding in the EVM

Encoding is a generic term “to create byte representation of high-level code.” While Solidity is a high-level language, in contrast, EVM is a low-level system with no functions or contracts, only bytes. As a result, developers must encode every contract, function, and value in Solidity to ensure that the EVM can understand and execute them.

That said, encoding has its set of rules depending on what you are encoding, some of which are:

  • The Contract Application Binary Interface (ABI) is the standard way for Ethereum smart contracts to interact with contracts outside the blockchain and for contract-to-contract calls. Developers encode each data according to its type. The encoding is not self-describing, so you’ll need a schema to understand and decode. Note that there are two types: dynamic and static types. Dynamic types are encoded separately after the current block, while static types are encoded in place or known at compile time. The following types are called “dynamic”:
  • bytes
  • string
  • T[]for any T

All other types are static.

  • Design criteria for the encoding: Encoding is designed to have the following properties — which prove helpful if some arguments are nested arrays:
  1. The number of reads required to access a value is dependent on the depth of the value in the argument array, eg: four reads are needed to retrieve i_a[m][d][f].
  2. The data of a variable or an array is not interleaved — mixed with different variables or data structures, is relocatable, and only uses relative addresses.

There are other rules; transactions are encoded like this:

  • First 4 bytes are the function selector (F)
  • The rest are encoded parameters (P)

You can learn more about how to encode what here. With the correct encoding, every time an EVM client receives a transaction, it can decode that raw transaction while accurately knowing which function to call and what parameters to use.

At this point, you understand how encoding works in the EVM. But we still haven’t answered the Why question. Here’s why: Encoding helps the EVM understand raw transaction data or values. Your compiler generates opcodes from the source code, and encoding creates bytecodes from opcodes. Another reason is that it is a standard. E.g., When encoding function parameters, it is common to pad them with zeros so they always take up 32 bytes, e.g., a single uint256 value. If you don’t, it would be ambiguous if you were encoding two uint128 values (each 16 bytes) as two separate values or as one big 32-byte value., without padding them with zeros.

Where to use it

Everything in EVM has to be represented with bits and bytes, so everywhere! Several tools exist for ABI-encoding, like ABI-Encoder (Ikr), Rust, ethers.js, Web3.js, etc. As a developer, you’ll use it for creating raw transactions and manipulating values, like when converting between data types such as bytes and string or between uint types of different sizes.

Examples of ABI encoding functions in Solidity

1. abi.encodeWithSignature

This function takes the function signature and its parameters as arguments and returns a byte array containing the encoded data. For example:

 function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}

function test() public pure {
uint256 a = 123;
uint256 b = 456;
bytes memory data = abi.encodeWithSignature("add(uint256,uint256)", a, b);
}

In the above example, the add function takes two uint256 input parameters and returns a uint256 value. The test function calls the add function and encodes the input parameters using the abi.encodeWithSignature function.

2. abi.encode

The abi.encode function takes the parameters as arguments and returns a byte array containing the encoded data. This is useful when you don’t know the function signature at compile time. For example:

function test() public pure {
uint256 a = 123;
uint256 b = 456;
bytes memory data = abi.encode(a, b);
}

In this example, the test function encodes the input parameters using the abi.encode function.

3. abi.encodePacked

The abi.encodePacked function takes the parameters as arguments and returns a byte array containing the tightly packed encoded data. This means that the data is not padded to fit into 32-byte chunks. This is useful for saving gas costs by reducing the data size. For example:

  function test() public pure {
uint256 a = 123;
uint256 b = 456;
bytes memory data = abi.encodePacked(a, b);
}

In this example, the test function encodes the input parameters using the abi.encodePacked function.

Summary

In conclusion, while ABI encoders are well documented, the reasons for their use are unclear. However, as we’ve seen, decoding and encoding data in standardized formats are necessary for creating smart contracts that can efficiently interact with other contracts and external applications. Furthermore, by using ABI encoders, developers can ensure their contracts are accessible to the broader Ethereum ecosystem and enjoy the benefits of interoperability. So, the next time you’re working on a project, remember the power of ABI encoding and its important role in creating secure and interoperable smart contracts.

--

--

Harvesto Orlando
Coinmonks

I write well-researched, engaging, opinionated articles on the applications of blockchain and crypto... Open to Copywriting opportunities.