Solidity: Why use assembly?

Seher Saylik
3 min readJan 18, 2023

--

While building smart contracts with Solidity, low-level language can be required in some cases. This level of language that is converted to machine code is referred to as assembly. Solidity supports Yul language which is for using inline assembly in the code.

Assembly’s role here is to manipulate directly the EVM using opcodes to gain significantly more control and to be able to execute logic that might not be achievable with plain Solidity. However, Yul is not the same as EVM opcodes although it supports most of them.

Terminology

Assembler: A program that converts assembly language to machine code.
Assembly: Set of instructions that are executed by an assembler.
Opcode: A part of a machine language instruction that demonstrates which operation is going to be executed by the CPU.

Here we have some of the Yul instructions. For the full list, check here.

! Some scenarios where assembly can be used are listed below. Here, it should be noted that now Solidity also covers these instructions. For instance, create2 instructor got Solidity support in 2022. Yet, it only takes the parameter of data to be used to salt. You can utilize more specific, tailored instructions with assembly.

Let’s say we have a factory contract that creates different Staking contracts for each given token address. How can we access staking contracts that have already been created or will be created in the future by simply entering the token address through another contract? For that, we can use assembly’s create2 instruction to create a new staking contract address with the parameters that we want.

In the example below, to create a salted contract with assembly, bytecode and salt data is required.

Parameters of create2(v, p, n, s): returns the new address

  • v : amount of wei to be sent
  • p and n : create new contract with code mem[p…(p+n)) at
    address keccak256(0xff . this . s . keccak256(mem[p…(p+n)))
  • s : any data(bytes32, uint256..etc.) for salting

The returned hashedByte value is going to be a bytes variable such as: 0x64fb713c5d2c04c6cda99addb7577c7b8c0fbea90b643e57a563b712c133abfa

And the returned staking address: 0x097826251b09Eee7ba4bc9dbA758689361a5B353

So the aim is to reach the created Staking addresses only via their token addresses and the factory address that created it.

2. Build proxy/logic contracts

To create upgradable contracts, a logic contract and proxies are required. Logic contract is one that keeps the whole storage that is maintained by the proxies. It’s called by proxies using the delegatecall. Therefore, logic contract’s storage is always persistent and proxy contracts can be updated.

Although Solidity provides a delegatecall function, it only returns true/false whether the call succeeded and doesn’t allow you to manage the returned data.

Parameters of delegatecall(g, a, in, insize, out, outsize):

  • g: required Gas to execute the function
  • a: address of the logic contract
  • in: memory pointer for where data starts
  • insize: the size of the data we’re sending in.
  • out: returned value from calling the logic contract. This value can be reached via returndata instruction.
  • outsize: 0 size of the returned data.

Upgradable Example Logic contract:

Proxy contract:

With the above implementation, logic contract can be called without its interface and state updates are made on the proxy contract by using its storage. As we can see in the assembly block, if the delegatecall fails, transaction will revert. Instead of reverting, any other different implementation could have been executed too.

To sum up, assembly can be used in cases:

  • Memory management to allocate memory by pointing the slots manually
  • Creating salted/customized contract addresses
  • Reasons related to Gas efficiency
  • Calling variables, and functions with only their names and contract addresses without using the interface.

It’s recommended to use assembly when required like in the above examples since it is more vulnerable to making mistakes than plain Solidity.

--

--