Message calls in Ethereum

3 minute read



In the Ethereum Virtual Machine (EVM), smart contracts can call other contracts and trigger their execution. This allows for complex contracts with deeply nested message calls.

Below I provide a short summary related to the message calls section of Ethereum’s Yellow Paper. Then, I describe each message call in more detail.

Message call

As outlined in the Yellow Paper, message call is the function Θ that takes 12 arguments. See the paper for details associated with each value.


Θ Input values:

  1. σ - world state
  2. s - sender’s address
  3. o - transaction originator’s address
  4. r - recipient’s address
  5. c - code owner’s address
  6. g - available gas
  7. p - gas price
  8. v - value to be be transferred from sender to recipient
  9. v with overline - value used in the call’s execution context
  10. d - input data of the call
  11. e - present depth of the message call stack
  12. w - the permission to make modifications to the state

Output values:

  1. σ - new state
  2. g - remaining gas
  3. A - substate
  4. z - execution halt status
  5. o - output data

Message call starts with transferring value v from sender’s address s to recipient’s address r. All other input values are used in the execution context of the call.

If the message call stack e exceeds 1024 or there is not enough value to transfer v from sender’s address, the message call is not executed.

Message call types

EVM has 4 types of message call instructions:

  1. CALL


CALL is the most straightforward type of message call. It takes 7 arguments, the last four of which are used for reading input data from the memory and writing the result of the execution to the memory. The first three arguments:

  1. μ0 - gas.
  2. μ1 - recipient’s address.
  3. μ2 - value that will be transferred from sender to recipient.

So our message call function Θ will look like Θ(σ, I_a, I_o, μ1, μ1, C_callgas, I_p, μ2, μ2, i, I_e + 1, I_w) where:

  • I - current execution environment
  • C_callgas - cost of the call operation that is calculated using μ0 and σ
  • i - input data read from memory

We can see the recipient and code owner are the same account, and the same value is used for transferring and execution.


CALLCODE is used for a message call into the current account with an alternative account’s code. Arguments of this instruction are identical to CALL except for the forth parameter, where the recipient is the same as the account.

CALLCODE function:

Θ(σ, I_a, I_o, I_a, μ1, C_callgas, I_p, μ2, μ2, i, I_e + 1, I_w).


This instruction was introduced by Ethereum Improvement Proposal (EIP) №7. DELEGATECALL is used for a message call into the current account with an alternative account’s code, but the current values for sender and value are persistent.

As described in the EIP, propagating the sender and value from the parent scope to the child scope makes it easier for a contract to store another address as a mutable source of code and ‘‘pass through’’ calls to it, as the child code would execute in essentially the same environment as the parent.

This instruction omits a μ2 argument, otherwise it is the same as CALL.


Θ(σ, I_s, I_o, I_a, μ1, μ0, I_p, 0, μ2, i, I_e + 1, I_w)


This instruction was introduced by EIP №214. As stated in the EIP’s summary, the opcode can be used to call another contract (or itself) while disallowing any modifications to the state during the call (and its subcalls, if present). Any opcode that attempts to modify the state results in an exception rather than performing the modification.

STATICCALL is equivalent to CALL except μ2 is replaced with 0 and the w flag is false.

STATICCALL function:

Θ(σ, I_a, I_o, μ1, μ1, C_callgas, I_p, 0, 0, i, I_e + 1, false)

Note: The w flag is referred to as the STATIC flag and was introduced specifically for STATICCALL.

See also