New to blockchain software development? Read my beginners guide here

Guide to Solidity's staticcall and how to use it

Created on August 2022 β€’ Tags: ethereumsolidityguides

A guide to using the Solidity staticcall


Table of Contents for Guide to Solidity's staticcall and how to use it


Solidity had a new feature added back in 2017 (https://github.com/ethereum/EIPs/pull/214) to add STATICCALL.

This was added in EIP-214 - https://github.com/ethereum/EIPs/blob/master/EIPS/eip-214.md

The staticcall is a security improvement, as it allows a contract to call another contract (or itself) without modifying the state.

If you try to call something in another contract with staticcall, and that contract attempts to change state then an exception gets thrown and the call fails.

staticcall works in a similar way as a normal call (without any value (sending eth) as this would change state). But when staticcall is used, the EVM has a STATIC flag set to true. Then, if any state modification is attempted, an exception is thrown. Once the staticcall returns, the flag is turned off.

How to use staticcall (example syntax)

[success, returnData] = aContratAddress.staticcall(bytesToSend)

Here is an example of calling staticcall. It is similar to call().

// basic example, calling staticcall with encodeWithSignature
(bool success,) = someContract.staticcall(abi.encodeWithSignature("foo(uint256)", 100));

// or if you already have the data to send, and want to see the result:
(bool isSuccess, bytes memory response) = someContract.staticcall(data);

Here is an example of calling staticcall in Solidity assembly (the same as calling call() but without the value).


assembly {
staticcall(16000, addr, add(data, 32), mload(data), 0, 0)
}

In the example above (based on https://ethereum.stackexchange.com/a/101452):

  • 16,000 gas
  • address target contract address
  • add(data, 32) input
  • mload(data) input size
  • 0 output
  • 0 output size

When will staticall throw exceptions?

An exception will also be thrown if the code (opcodes in brackets):

  • tries to deploy a new contract (CREATE and CREATE2)
  • emits logs (LOG0, LOG1, LOG2, LOG3, LOG4)
  • makes state changes (SSTORE)
  • anything that uses call() with a value (sending eth)

Why and when to use staticcall

One of the main reasons to use staticcall is to avoid reentrancy vulnerabilities.

Spotted a typo or have a suggestion to make this crypto dev article better? Please let me know!

See all posts (70+ more)

See all posts (70+ more)

Was this post helpful? πŸ“§

If you liked this content and want to receive emails about future posts like this, enter your email. I'll never spam you.

Or follow me on @CryptoGuide_Dev on twitter

By using this site, you agree that you have read and understand its Privacy Policy and Terms of Use.
Use any information on this site at your own risk, I take no responsibility for the accuracy of safety of the information on this site.