EIPs/EIPS/eip-2003.md

136 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
eip: 2003
title: EVMC modules for implementations of precompiled contracts
author: Paweł Bylica (@chfast), Alex Beregszaszi (@axic)
discussions-to: https://github.com/ethereum/evmc/issues/259
status: Draft
type: Standards Track
category: Interface
created: 2019-05-09
requires: 1352
---
## Abstract
[EVMC] specifies a generic API for Ethereum execution engines.
This EIP specifies a way of providing implementations of Ethereum precompiled contracts
using the [EVMC VM API].
## Specification
For the complete [EVMC] specification visit the [EVMC documentation] first.
This EIP is based on and is compatible with EVMC ABI version 6.
The EVMC module with implementations of precompiled contracts SHOULD:
1. Advertise the [`EVMC_CAPABILITY_PRECOMPILES`] capability
in the [`get_capabilities()`] method.
2. Implement the [`execute()`] method in the following way:
1. Validate the incoming execution request requirements:
1. The message kind ([`evmc_message::kind`]) is a call ([`EVMC_CALL`]).
2. The call destination address ([`evmc_message::destination`])
is within the range of precompiled contracts defined by [EIP-1352].
3. There is no code provided (the `code` argument is `NULL` and `code_size` argument is `0`).
If the requirements are not fulfilled, abort execution with the [`EVMC_REJECTED`] status code.
2. Check if the call destination address ([`evmc_message::destination`])
targets existing precompiled contract.
Consider the EVM revision ([`evmc_revision`]) requested by
the `rev` parameter of [`execute()`].
If yes, execute as follows:
1. Inspect the input data ([`evmc_message::input_data`], [`evmc_message::input_size`])
and calculate the _gas cost_ of the execution.
2. Compute the amount of _gas left_ after execution by
subtracting the _gas cost_ from the call gas limit ([`evmc_message::gas`]).
3. If _gas left_ is negative,
abort execution with the [`EVMC_OUT_OF_GAS`] status code.
4. Otherwise,
execute the code of the precompiled contract,
return the [`EVMC_SUCCESS`] status code, the output and _gas left_
([`evmc_result::output_data`], [`evmc_result::output_size`], [`evmc_result::gas_left`]).
3. Otherwise, emulate execution of empty code by returning
the [`EVMC_SUCCESS`] status code
and _gas left_ equal the call gas limit ([`evmc_message::gas`]).
Precompiled contract implementations are allowed to return two more EVMC error codes:
- [`EVMC_FAILURE`] if the failure was caused due to something other than out of gas (e.g. input validation error)
- [`EVMC_REVERT`] if the precompile doesn't want to forfeit all supplied gas (as of May 2019 no such precompile exists)
The Client is not required to provide the Host interface ([`evmc_context`] argument of [`execute()`] is set to NULL).
Therefore, the precompiled contracts implementation MUST NOT access the `evmc_context`.
## Rationale
It is very unlikely that any precompile will need to access or modify a contract state.
Not requiring the Client to implement the EVMC Host interface removes the big portion of work
needed for full EVMC integration.
## Test Cases
EVMC provides the [evmc-vmtester] tool for checking compatibility with the EVMC specification.
## Implementations
- [Example of Precompiles VM implementation][example_precompiles_vm.cpp]
- [ewasm precompiles]
- Aleth code for precompiles
- Parity code for precompiles
- [EIP-1962 implemented as an EVMC precompile module](https://github.com/axic/eip1962-evmc)
## References
- [EVMC Ethereum Client-VM Connector API][EVMC]
- [EVMC documentation]
- [EVMC VM Implementation Guide][EVMC VM API]
- [EIP 1352: Specify restricted address range for precompiles/system contracts][EIP-1352]
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
[EIP-1352]: https://eips.ethereum.org/EIPS/eip-1352
[EVMC]: https://github.com/ethereum/evmc
[EVMC documentation]: https://ethereum.github.io/evmc/
[EVMC VM API]: https://ethereum.github.io/evmc/vmguide.html
[evmc-vmtester]: https://ethereum.github.io/evmc/vmtester.html
[example_precompiles_vm.cpp]: https://github.com/ethereum/evmc/blob/master/examples/example_precompiles_vm/example_precompiles_vm.cpp
[ewasm precompiles]: https://github.com/ewasm/ewasm-precompiles
[`EVMC_CALL`]: https://ethereum.github.io/evmc/group__EVMC.html#ggab2fa68a92a6828064a61e46060abc634abcf3ae29d9a88ff70b98374fc665694a
[`EVMC_CAPABILITY_PRECOMPILES`]: https://ethereum.github.io/evmc/group__EVMC.html#gga44f9ecb88cf6422a0072936494fd6ac7a43ea2aa7b099a2d67bc53c118ff3683d
[`EVMC_FAILURE`]: https://ethereum.github.io/evmc/group__EVMC.html#gga4c0be97f333c050ff45321fcaa34d920aed5b2a4afa5a47af732569445920a4a9
[`EVMC_OUT_OF_GAS`]: https://ethereum.github.io/evmc/group__EVMC.html#gga4c0be97f333c050ff45321fcaa34d920abfc47f75656c996c0b29c0553c00fc18
[`EVMC_REJECTED`]: https://ethereum.github.io/evmc/group__EVMC.html#gga4c0be97f333c050ff45321fcaa34d920a2f3e0d8777f8d974ead27ae2a6eb2005
[`EVMC_REVERT`]: https://ethereum.github.io/evmc/group__EVMC.html#gga4c0be97f333c050ff45321fcaa34d920aed708e84d49cc1270e54ec20b0ca0a05
[`EVMC_SUCCESS`]: https://ethereum.github.io/evmc/group__EVMC.html#gga4c0be97f333c050ff45321fcaa34d920a4bc3069fec2bab2a55355a72b7db68b7
[`execute()`]: https://ethereum.github.io/evmc/structevmc__instance.html#a0823ebff21f9b0395b157e8c6b14a207
[`get_capabilities()`]: https://ethereum.github.io/evmc/structevmc__instance.html#ae63b9ca898aa41cbd1e2fe86ca8f4e1c
[`evmc_message::destination`]: https://ethereum.github.io/evmc/structevmc__message.html#a88ecfaa03a85a31c6da36fa043b98cea
[`evmc_message::input_data`]: https://ethereum.github.io/evmc/structevmc__message.html#a1adee3454b105eb29cd659ee0cf65c77
[`evmc_message::input_size`]: https://ethereum.github.io/evmc/structevmc__message.html#a2cf1deebd0dbbb20f25ecdfa299f4b5d
[`evmc_message::gas`]: https://ethereum.github.io/evmc/structevmc__message.html#ae8deff46588584fa27890e74c82db5e7
[`evmc_message::kind`]: https://ethereum.github.io/evmc/structevmc__message.html#a691cb93e81d6dfd4fd7e2fa3d06a6bfa
[`evmc_result::gas_left`]: https://ethereum.github.io/evmc/structevmc__result.html#af8478c93dbcc3cb2876037c5a5afd4c0
[`evmc_result::output_data`]: https://ethereum.github.io/evmc/structevmc__result.html#a61978e85f9d795a7b9695b9cbf1748d6
[`evmc_result::output_size`]: https://ethereum.github.io/evmc/structevmc__result.html#a93bb7419aff492cdef754421c6d74e26
[`evmc_revision`]: https://ethereum.github.io/evmc/group__EVMC.html#gae5759b1590071966ccf6a505b52a0ef7