6.5 KiB
Nim EVMC - Ethereum VM binary compatible interface
Introduction to EVMC
Nim EVMC - Ethereum Virtual Machine binary compatible interface.
This the Nim version of EVMC, the Ethereum Client-VM Connector API, whose description says:
The EVMC is the low-level ABI between Ethereum Virtual Machines (EVMs) and Ethereum Clients. On the EVM side it supports classic EVM1 and ewasm. On the Client-side it defines the interface for EVM implementations to access Ethereum environment and state.
EVMC provides a way for Ethereum applications (like Nimbus, Geth and OpenEthereum) which use EVM functionality to "plug in" different implementations of the EVM (or EWASM).
The interface is binary compatible, allowing different EVMs to be loaded as shared libraries or statically linked in. This supports innovation from different teams in areas like performance, new operations and hard fork support. "Precompiles" can be loaded as separate libraries as well. (These are specially optimised contracts, generally for cryptography support.)
The interface also makes a good module boundary between the EVM and other parts of a full Ethereum implementation. EVMC has detailed documentation. It is mainly of interest to developers of Ethereum clients and Ethereum Virtual Machines, but you can learn interesting things about how the EVM fits into the Ethereum system from what kinds of calls are in this API.
Current status
2021-06-27
- Supports EVMC API version 9.0.0. This API is suitable for transactions up to and including Ethereum London.
2021-05-08
- Supports EVMC API version 8.0.0. This API is suitable for transactions up to and including Ethereum Berlin, the current version on mainnet at the time of writing. Berlin went live on 15th April 2021.
2021-05-06
- Supports EVMC API version 7.5.0. This API is suitable for transactions up to and including Ethereum Istanbul. That's everything up to 15th April 2021 on mainnet. It recognises the later Ethereum Berlin but does not have all the functions necessary to run Berlin.
2019-12-16
- Supports EVMC API version 7.1.0.
2018-02-02
- Initial version for EVMJIT. EVMC API doesn't have a version yet.
Used by
Nim EVMC is a core component of Nimbus Eth1, an Ethereum client written in Nim, designed to use minimal system resources and run on smaller devices. Because EVMC provides a fairly clean module boundary between the EVM and other parts of a full Ethereum implementation, after studying the performance and other characteristics, Nimbus Eth1 decided to adopt EVMC as a first class module boundary inside the project, using some extensions to get extra functionality not in the base EVMC definition.
(See also its sibling project Nimbus Eth2, which is very active on the Ethereum 2 proof-of-stake network already!)
Nim EVMC by itself does not have a large test suite, just a basic one. But it is tested by daily extensive use with Nimbus Eth1.
It has also been used in the past with The Ethereum EVM JIT. EVMJIT is no longer maintained, and we don't use it any more. (Fun fact: EVMC was originally part of EVMJIT until it was forked off to support many EVMs).
See the EVMC main page for a more recent list of other EVMs and clients that work with EVMC, and can in principle be used with each other.
Installation and test
Nim EVMC can be fetched and used as a standard Nimble package, nim-evm
.
The main API is found in the file evmc/evmc.nim
which is well commented, and
imported into other programs just with import evmc/evmc
.
All the EVMC types, enums and functions are available, with the standard names defined in the EVMC Documentation.
Additional "glue" functions for an EVM to use are available through import evmc/evmc_nim
. However, evmc/evmc_nim
is not used by Nimbus Eth1 so
it's mainly useful as an example. It is used by the tests in this package
though.
To run this package's tests, simply run nimble test
. It exercises calls
between C and Nim in both directions and of course everything should pass.
It's not a thorough test of EVM functionality, which would be very complex. There's no need, because there are other extensive EVM testsuites, not designed specially for EVMC, that can be used with Nim EVMC due to its plugin nature.
Building EVMJIT and other EVMs
We used to test with EVMJIT, but EVMJIT is no longer maintained. The old version should still work, although it will be out of date for current Ethereum developments.
To use EVMJIT, you will need to build it as a shared library by replacing
add_library(evmjit ${SOURCES} gen/BuildInfo.gen.h)
with
add_library(evmjit SHARED ${SOURCES} gen/BuildInfo.gen.h)
in file
libevmjit/CMakeLists
.
Other EVM implementations can be used, if you can build them as a shared
library. Once you have done this, copy or modify the file evmc/evmjit.nim
in
Nim EVMC with appropriate names changed. Alternatively you can look at
the Nimbus Eth1 implementation
which is more feature complete.
License
This package is licensed under either of
- Apache License, version 2.0, (LICENSE-APACHEv2)
- MIT license (LICENSE-MIT)
at your option. The files in this package (except those mentioned below) may not be copied, modified, or distributed except according to those terms.
Files under subdirectory tests/evmc_c
are third-party files from Ethereum
Client-VM Connector API (EVMC), and may only
be used, copied, modified or distributed according to the licensing terms of
that distribution. Those terms are the Apache License, version 2.0,
(LICENSE-APACHEv2).