EIP-214 The static call instruction STATICCALL (New opcode STATICCALL)

Final · EVM & execution · EIP status Final · created 2017-02-13

Adds a new instruction, STATICCALL (0xfa), which calls another contract while disallowing any state changes within that call. Any attempt to change state is treated as an exception.

Why it is needed

Currently, once a contract calls another contract, there is no way to prevent the callee from doing whatever it wants as long as there is enough gas. So after making an ordinary call, unless you know exactly what code the called contract runs, you cannot assume anything about the state afterward. Since transaction order is also unknown until a miner finalizes it, even an outside observer cannot be certain of the state in every case. This proposal opens up the simplest way to restrict what the counterparty can do during a call: it becomes safe to assume that every account's state is the same before and after a static call.

What changes

Today

After EIP-214

Who is affected

In depth

Introduction of the STATIC flag

A new STATIC flag is introduced into the virtual machine. Its initial value is false, and that value is always copied down to sub-calls. The sole exception is the new opcode STATICCALL, which sets the flag to true for the child execution. When the call returns, the flag is reset to its value before the call. Because of this flag-propagation rule, the ban on state changes holds for sub-calls of every depth inside a static call.

Opcode format: 0xfa, 6 arguments

The opcode for STATICCALL is 0xfa. Its behavior is equivalent to CALL, but it takes only 6 arguments. CALL's "value" argument is dropped and treated as 0. In other words, a static call cannot send ether. Calling oneself is also possible.

List of forbidden state-changing operations

Attempting a state-changing operation inside an execution instance where STATIC is true raises an exception instead of being performed. These operations are CREATE, CREATE2, LOG0, LOG1, LOG2, LOG3, LOG4, SSTORE, SELFDESTRUCT, and a CALL with nonzero value. As an exception, CALLCODE is not treated as a state change even with nonzero value.

Design intent: guaranteeing pure functions

This proposal lets a contract make a call that is clearly guaranteed not to change state at all. Since that call only returns output and does nothing else, it is a pure function, giving developers and reviewers confidence that no reentrancy bug or other issue can arise from that particular call. The original text adds that this also makes it easier to implement purely functional high-level languages.

Backward compatibility and current status

This only adds a new opcode and does not change the behavior of any other opcode. It is therefore backward compatible with existing contracts that neither use the new opcode nor are called through it. This EIP was proposed on February 13, 2017 by Vitalik Buterin and Christian Reitwiessner, and its status is Final, meaning the spec is already settled.

Original EIP · ← EIPs