EIP-7666 Moving the identity precompile to EVM code (EVM-ify the identity precompile)
Hegota Declined for Inclusion · EVM & execution · EIP status Draft · created 2024-03-31
Removes the identity precompile at address 0x04 (a built-in function that returns its input unchanged) and puts 7 bytes of EVM code that do the same job in its place. The functionality stays the same, and clients have one fewer precompile to implement separately.
Why it is needed
Ethereum has several precompiles. These are special functions that client software implements directly outside the EVM. According to the source, nearly half of them see little use yet keep creating maintenance cost, raise the risk of consensus bugs, and add development burden when building new clients in languages suited to ZK-EVMs or formal verification. The identity precompile is the simplest precompile, returning the input it receives (calldata) unchanged. It was introduced originally because memory copying is a common operation and there was no instruction to do it directly. Later, the MCOPY instruction arrived with EIP-5656, and the criteria for which functions to accept as instructions also changed. Now this precompile can be replaced with a very short piece of EVM code. This proposal therefore starts the process of cleaning up little-used precompiles with the simplest case.
What changes
Today
- Address 0x04 operates as the identity precompile that clients implement in their own code.
- Every client, including ZK-EVM and formal verification implementations, must implement and maintain this precompile separately.
- Little-used precompiles keep remaining, creating maintenance cost and consensus bug risk.
After EIP-7666
- At the start of the block where the fork activates, 7 bytes of EVM code are placed at address 0x04, and from that block on it is no longer treated as a precompile.
- The function of returning the input unchanged stays the same, and only the gas cost changes slightly.
- The number of precompiles clients must implement drops by one, and a path opens to apply the same approach to other precompiles.
Who is affected
- Users: There is no change you will notice directly. Contracts that call 0x04 get the same results as before.
- Wallet & app developers: Contracts that call address 0x04 get the same result, but the gas cost changes slightly. The source does not give specific figures for the difference.
- Client teams: Removes the native implementation of the identity precompile and implements placing EVM_CODE at 0x04 at the start of the fork block. This especially reduces the burden on ZK-EVM and formal verification implementations.
In depth
What changes, and the constants
What this proposal changes comes down to two constants. IDENTITY_PRECOMPILE_ADDRESS is 0x0000....0004 and EVM_CODE is 0x365f5f37365ff3. At the start of execution of the block in which the fork activates, the code of IDENTITY_PRECOMPILE_ADDRESS is set to EVM_CODE. From that block onward (including that block), this address is no longer treated as a precompile. That is, instead of handling calls to 0x04 with a natively implemented function, a client executes the bytecode stored at that address in the EVM, exactly like any other contract.
What EVM_CODE does
EVM_CODE 0x365f5f37365ff3 is 7 bytes and corresponds to the following instruction sequence: CALLDATASIZE PUSH0 PUSH0 CALLDATACOPY CALLDATASIZE PUSH0 RETURN. The first four instructions copy the entire call data starting at memory offset 0. CALLDATASIZE pushes the length, two PUSH0 instructions push 0 for the copy source offset and the memory destination offset onto the stack, and CALLDATACOPY performs the copy. The last three instructions return the same memory range. After CALLDATASIZE and PUSH0 push the length and the start offset 0, RETURN returns that range. The returndata is therefore identical to the input, and the behavior matches the identity precompile. The source describes this as the least disruptive change, one that preserves functionality while reducing the number of precompiles by 1. PUSH0 is an instruction introduced in EIP-3855, so the source lists EIP-3855 as a prerequisite (requires).
Why start with the identity precompile
The source points out that Ethereum has many precompiles and that nearly half of them have no clear use. Unused precompiles still create ongoing maintenance costs, raise the risk of consensus bugs, and increase the development burden when implementing new clients in languages suited to ZK-EVM or formal verification. This proposal therefore presents a procedure for gradually retiring little-used precompiles, and picks the simplest one, the identity precompile, as the first target. The identity precompile was introduced at a time when memory copying was a common operation but no instruction existed to do it directly. Later, the criteria for which functions to accept as instructions changed, and the MCOPY instruction was introduced by EIP-5656. The source notes that the same technique could later be applied to more complex precompiles, such as rarely used hash functions and MODEXP.
Compatibility, gas, security
EVM_CODE has the same functionality as the identity precompile. However, because a precompile call becomes ordinary EVM code execution, the gas cost changes slightly. The source explains that gas repricing has already happened many times on Ethereum and that its effects are well understood. The source does not give specific figures for the gas difference. On security, since no new functionality is added and nothing existing becomes cheaper, the source states that there are no security concerns.
Status and fork discussion
This proposal is in Draft status, so the specification may still change. It has been discussed twice on core developer calls. At ACDE #242 on 07.30, EIP-7666, which turns the identity precompile into EVM code, was accepted as a candidate for the Hegota fork at the PFI (Proposed for Inclusion) stage, together with EIP-8200 as its companion proposal. At ACDE #247 on 10.08, EIP-7666 was removed from the Hegota candidates (DFI). The reasons were edge cases in gas pricing and the small value gained.