System Contracts


Many EVM instructions require special handling by the System Contracts. Among them are: ORIGIN, CALLVALUE, BALANCE, CREATE, SHA3, and others. To see the full detailed list of instructions that require special handling, see the EVM instructions referencearrow-up-right.

There are several types of System Contracts from the perspective of how they are handled by the Validium Network Era compilers:

Environmental Data Storage

Such storage contracts are accessed with static calls in order to retrieve values for the block, transaction, and other environmental entities: CHAINID, DIFFICULTY, BLOCKHASH, etc.

One good example of such contract is SystemContextarrow-up-right that provides the majority of the environmental data.

Since EVM is not using external calls for these instructions, we must use the auxiliary heaparrow-up-right for their calldata.

Steps to handle such instructions:

  1. Store the calldata for the System Contract call on the auxiliary heap.

  2. Call the System Contract with a static call.

  3. Check the return status code of the call.

  4. Revert or throwarrow-up-right if the status code is zero.

  5. Read the ABI data and extract the result. All such System Contracts return a single 256-bit value.

  6. Return the value as the result of the original instruction.

For reference, see the LLVM IR codegen source codearrow-up-right.

KECCAK256 Hash Function

Handling of this function is similar to Environmental Data Storagearrow-up-right with one difference:

Since EVM also uses heap to store the calldata for KECCAK256, the required memory chunk is allocated by the IR generator, and Validium Network Era compiler does not need to use the auxiliary heaparrow-up-right.

For reference, see the LLVM IR codegen source codearrow-up-right.

Contract Deployer

See handling CREATEarrow-up-right and dependency code substitution instructionsarrow-up-right on Validium Network Era documentation.

For reference, see LLVM IR codegen for the deployer callarrow-up-right and CREATE-related instructionsarrow-up-right.

Ether Value Simulator

EraVM does not support passing Ether natively, so this is handled by a special System Contract called MsgValueSimulatorarrow-up-right.

An external call is redirected through the simulator if the following conditions are met:

  1. The callarrow-up-right has the Ether value parameter.

  2. The Ether value is non-zero.

Calls to the simulator require extra data passed via ABI using registers:

  1. Ether value.

  2. The address of the contract to call.

  3. The system call bitarrow-up-right, which is only set if a call to the ContractDeployerarrow-up-right is being redirected, that is CREATE or CREATE2 is called with non-zero Ether.

Passing Ether value in EraVM is implemented by using a combination of:

The process of setting up a value and capturing it is described in details in the section Context Register of the EraVM specificationarrow-up-right.

For reference, see the LLVM IR codegen source codearrow-up-right.

Simulator of Immutables

See handling immutablesarrow-up-right on Validium Network Era documentation.

For reference, see LLVM IR codegen for instructions for immutablesarrow-up-right and RETURN from the deploy codearrow-up-right.

Event Handler

Event payloads are sent to a special System Contract called EventWriterarrow-up-right. Like on EVM, the payload consists of topics and data:

  1. The topics with a length-prefix are passed via ABI using registers.

  2. The data is passed via the default heap, like on EVM.

For reference, see the LLVM IR codegen source codearrow-up-right.

Auxiliary Heap

Both zksolcarrow-up-right and zkvyperarrow-up-right compilers for EraVM operate on the IR levelarrow-up-right, so they cannot control the heap memory allocator which remains a responsibility of the high-level source code compilersarrow-up-right emitting the IRs.

However, there are several cases where EraVM needs to allocate memory on the heap and EVM does not. The auxiliary heap is used for these cases:

Returning immutablesarrow-up-right

  1. Returning immutables from the constructor.

  2. Allocating calldata and return data for calling the System Contracts.

While the ordinary heap contains calldata and return data for calls to user contracts, auxiliary heap contains calldata and return data for calls to System Contracts. This ensures better compatibility with EVM as users should be able to call EraVM-specific System Contracts in a transparent way, without System Contracts affecting calldata or return data. This prevents situations where calling System Contracts interferes with the heap layout expected by the contract developer.

For more details on the heaps, refer to the EraVM specification, which describes types of heapsarrow-up-right, their connections to the stack frames and memory growtharrow-up-right, and their role in communication between contractsarrow-up-right.

Last updated