Introduction
In this tutorial, we are going to walk through how we can generate a stateful precompile from scratch. Before we start, let's brush up on what a precompile is, what a stateful precompile is, and why this is extremely useful.
Background
Precompiled Contracts
Ethereum uses precompiles to efficiently implement cryptographic primitives within the EVM instead of re-implementing the same primitives in Solidity. The following precompiles are currently included: ecrecover, sha256, blake2f, ripemd-160, Bn256Add, Bn256Mul, Bn256Pairing, the identity function, and modular exponentiation.
We can see these precompile mappings from address to function here in the Ethereum VM:
These precompile addresses start from 0x0000000000000000000000000000000000000001
and increment by 1.
A precompile follows this interface:
Here is an example of the sha256 precompile function.
The CALL opcode (CALL, STATICCALL, DELEGATECALL, and CALLCODE) allows us to invoke this precompile.
The function signature of CALL in the EVM is as follows:
Precompiles are a shortcut to execute a function implemented by the EVM itself, rather than an actual contract. A precompile is associated with a fixed address defined in the EVM. There is no byte code associated with that address.
When a precompile is called, the EVM checks if the input address is a precompile address, and if so it executes the precompile. Otherwise, it loads the smart contract at the input address and runs it on the EVM interpreter with the specified input data.
Stateful Precompiled Contracts
A stateful precompile builds on a precompile in that it adds state access. Stateful precompiles are not available in the default EVM, and are specific to Avalanche EVMs such as Coreth and Subnet-EVM.
A stateful precompile follows this interface:
A stateful precompile injects state access through the PrecompileAccessibleState
interface to provide access to the EVM state including the ability to modify balances and read/write storage.
This way we can provide even more customization of the EVM through Stateful Precompiles than we can with the original precompile interface!
AllowList
The AllowList enables a precompile to enforce permissions on addresses. The AllowList is not a contract itself, but a helper structure to provide a control mechanism for wrapping contracts. It provides an AllowListConfig
to the precompile so that it can take an initial configuration from genesis/upgrade. It also provides functions to set/read the permissions. In this tutorial, we used IAllowList
interface to provide permission control to the HelloWorld
precompile. IAllowList
is defined in Subnet-EVM under ./contracts/contracts/interfaces/IAllowList.sol
. The interface is as follows:
You can find more information about the AllowList interface here.
Last updated on