A simple example for how to use Solidity’s Inline Assembly

Doug Crescenzi
Upstate Interactive
3 min readJan 30, 2019
http://upstate.agency

With Solidity being a relatively new language it has some limitations. To address this Solidity makes it possible to interweave your Solidity statements with its own version of inline assembly. This gives developers a way to build smart contracts that require more fine-grained control.

Writing manual assembly can be difficult due to the fact that the EVM is a stack machine. This makes it hard to address the correct stack slot and provide arguments to opcodes at the correct point on the stack. You can use Solidity’s defined inline assembly language to help you navigate these challenges and other issues when writing manual assembly.

Let’s take a look at an example.

The Multisig Wallet

Multisig wallets are used to add additional security to cryptocurrency transactions. The purpose of multisig wallets is to increase security by requiring multiple parties to agree on transactions before execution. Transactions can be executed only when confirmed by a predefined number of owners.

The Gnosis Multisig Wallet is a really nice open source implementation and a handy codebase to reference when it comes to using Solidity’s inline assembly.

How does the Gnosis Multisig Wallet use Solidity’s Inline Assembly

In the MultiSigWallet contract itself you’ll notice that a user must first submit a transaction via the submitTransaction function which takes three arguments: the destination address for the transaction, the value of ETH to send in the transaction, and lastly (and most importantly in the context of this article), the transaction’s data payload:

function submitTransaction(address destination, uint value, bytes data)

After a user submits a transaction, before it will ultimately execute, the other required parties must confirm the transaction via the confirmTransaction function. Upon confirmation, the executeTransaction function is called which in turn calls the external_call function in the contract.

Here is where we’ll find the use of Solidity’s inline assembly:

function external_call(address destination, uint value, uint dataLength, bytes data) 
private
returns (bool)
{
bool result;
assembly {
let x := mload(0x40)
let d := add(data, 32)
result := call(
sub(gas, 34710),
destination,
value,
d,
dataLength,
x,
0
)
}
return result;
}

What’s happening here is that the call opcode is used to interact with the EVM and execute the transaction. It takes seven arguments, including the original data payload from the submitTransaction function, and provides them to the call opcode at the correct point on the EVM’s stack.

You can learn more about Solidity’s inline assembly opcodes here.

Takeaways

  • There are times when developing your smart contracts where you’ll require more granular control and perhaps need to execute logic that may not be possible with just Solidity.
  • This would be difficult to do using manual assembly as we’d have to handle memory allocation and ensure we provide arguments to opcodes at the correct points on the EVM’s stack.
  • Solidity defined inline assembly helps us with this and provides high-level syntax which makes these circumstances easier to navigate.
  • It gives you more control over your smart contracts and lets you interact directly with the EVM using opcodes (like call).
  • That said, even though Solidity’s Inline assembly appears high-level, it is actually extremely low-level.
  • Ultimately, Solidity’s inline assembly gives you more control over your smart contracts and permits you to execute logic that may not be possible with just plain old Solidity

I hope you found this helpful! Please don’t hesitate to reach out if you have any questions or would be interested in learning more — doug@upstate.agency

PS — Here’s a great article from Elizabeth Binks that dives into Solidity’s inline assembly more in depth

--

--

Doug Crescenzi
Upstate Interactive

vp, software engineering @ Foundry, previously founding partner at Upstate Interactive (acq'd by Foundry in '22)