Standalone

Self-Hosted EVM

close button

Part VI

Delegate Calls and Callcodes

Besides direct calls, the EVM also supports two other types of calls: DELEGATECALL and CALLCODE.

DelegateCall

DELEGATECALL execute the callee's bytecode in the caller's context. For example, if A sends a transaction to B, and B makes a DELEGATECALL to C, then:

  • C's bytecode is being executed.

  • A is msg.sender.

  • B is address(this).

  • B's storage will be used in any storage.

Similar to how we implemented the previous calls, we will define an external function, ICrossTx.delegateCall, for opDelegateCall to call.

selfhosted_EVM_10.webp

For delegate calls, we now have 3 addresses to consider: that of the msg.sender, the caller (aka delegator), and the callee. All these can be passed to ICrossTx.delegateCall via the InternalInput structure.

Error

Expected Message

INSUFFICIENT_BALANCE_ERROR

sEVM: insufficient balance

READ_ONLY_ERROR

sEVM: read only

CallCode

CALLCODE is similar to DELEGATECALL, with one distinguishing difference: the msg.sender is not preserved. For example, if A sends a transaction to B, and B makes a CALLCODE to C, then:

  1. C's bytecode is being executed

  2. B is msg.sender

  3. B is address(this)

  4. B's storage will be used in any storage operations

Because of how similar CALLCODE is to DELEGATECALL, CALLCODE can be implemented by simply calling ICrossTx.delegateCall.

selfhosted_EVM_11.webp

Error

Expected Message

INSUFFICIENT_BALANCE_ERROR

sEVM: insufficient balance

READ_ONLY_ERROR

sEVM: read only

Your Task

Implement DELEGATECALL by defining:

  • opDelegateCall in contracts/libraries/Instructions.sol

  • delegateCall in contracts/sEVM.sol

Then, implement CALLCODE by defining:

  • opCallCode in contracts/libraries/Instructions.sol

Run tests in Questplay

To this end, the Great Archmage’s followers found the Academy, a location where all could come to learn. Soon, the Academy became the finest seat of learning ever known…