Exploring Solidity Objects: Address - Part 2
Dive into the world of Solidity in pursuit of leveling up! (Catching gotchas before gotchas get us)
In Part 1, we explored different address members and their use cases. While the previous article explored scenarios involving sending Ether, it is helpful to know that the functionalities extend beyond that. For instance, the call function is a low-level function which has the capability to invoke any function on any target contract by specifying the function signature and arguments in the ‘data’ parameter. (Security Note: call never reverts. It is our responsibility to handle unsuccessful transaction errors.)
Now, let’s delve into the final two members of the address object: staticcall and delegatecall. These members are also interchangeably referred as functions - particularly when describing their role in code execution through invocation.
The underlying concept of staticcall and delegatecall is relatively straightforward, as they are essentially specialized variants of the call function.
delegatecall
Let’s kick this off with delegatecall. This function allows state modifying instructions while preserving the original contract’s context (storage, sender address, and value).
At this point, you might be wondering about the terminology “delegatecall”. How exactly are the function calls “delegated”? Or rather, what is the mode of “delegation” here?
Let’s utilise the illustrative examples below to answer these questions!
Notice that the DelegateCaller Contract has a function setVars() which invokes the delegatecall function. When setVars() is called (DelegateCaller contract), the delegatecall invokes the setVars() function in the Caller contract but in the DelegateCaller execution environment. Thus, Caller contract has effectively delegated its function to DelegateCaller contract.
This could still be confusing. Let’s explore further through the video below! (Watch what happens when setVars() was called in DelegateCaller contract. Observe how the value variables change in the context of Caller and DelegateCaller contract.)
Were you able to identify the contract that had its value variable updated when delegatecall was invoked? Explore this code further here: Remix: delegatecall
This behavior might seem redundant at first when we can simply use call function. However, delegatecall enables use cases such as for proxy contracts - where only the implementation contract (i.e. Uniswap V2, V3) is upgraded to preserve the context of the proxy contract.
Having explored the complexities of delegatecall, let’s proceed to explore staticcall which is relatively simpler!
staticcall
In general, staticcall does not allow any state modifying instructions or capability to send ether. It will revert if there are any state changes during the function invocation. At a low-level, it disallows opcodes such as CREATE, SSTORE, SELFDESTRUCT, and few others. Personally, I view staticcall as a safer variant of the call function to read state.
In the example above, notice how the value variable for StaticCaller contract did not change. It remains as “0” even when Caller contract has been updated to store “100” in its value variable. Unlike delegatecall which allows state modifying instruction, staticcall only reads state of the target contract (Caller contract in this example).
As a treat, I have also included a function setVars() which purposefully calls a state modifying function from the target contract to simulate transaction failure. Watch the video towards the end to learn what happens when success returns false.
Explore this code further here: Remix: staticcall
You must be wondering about some use cases of staticcall. In ETH CC Brussels, Scroll introduced the experimental L1SLOAD precompile which uses staticcall under the hood. Hackers were able to explore novel methods of resolving ENS address, extending NFT ownership - all on L2. This highlights that, in this preliminary stage of experimentation, the potential opportunities for this function are virtually limitless.
Now that you have equipped yourself with an arsenal of knowledge on the address object, you are now capable of address-ing (Hehe! Pun intended) more intermediate to advanced level builds. Can’t wait to hear all about how you will be using this knowledge to level up your projects.
Thank you very much for reading. Feel free to reach out to me on my socials if you would like to engage with me on anything and everything related to building on Ethereum! I love learning with the community!



