Enclave EVM (eEVM) is an open-source, standalone, embeddable, C++ implementation of the Ethereum Virtual Machine. It was originally built to run within a TEE (ie, SGX enclave) on top of the Open Enclave SDK, for use with Microsoft's Confidential Consortium Blockchain Framework.
The main entry point is
evm::Processor::run(). You will need to provide
evm::Processor with an implementation of
evm::GlobalState to handle all interactions with permanent state. The source includes
evm::SimpleGlobalState as an example backed by
std::map, but other instances will likely want an implementation which provides permanent storage - perhaps a wrapper to read/write data from the Ethereum blockchain.
The implementation ignores all gas costs - gas is not spent, tracked, or updated during execution, and execution will never throw an outofgas exception. However, it may still be necessary to pass a sensible initial gas value to
evm::Processor::run() in case the bytecode calculates or verifies gas budgets itself. It also does not provide the precompiled contracts at addresses 1 to 8.
So far, the code is not particularly optimized in any dimension. In fact, it is in experimental state.
- CMake. Minimum version 3.10.
- Boost. Minimum version 1.60.0. We currently use Boost multi-precision ints, so require Boost to be available on the local machine. This is a header-only dependency - Boost does not need to be installed. We may replace this with another wide int implementation in the future.
Build and Test
We build and test eEVM on Linux and Windows on x86-64, but it should be functional cross-platform.
Build the static library and tests.
mkdir build cd build cmake .. make
It is also possible to build with Ninja or another generator of choice, and the code will compile with either GCC or Clang (other compilers are untested).
Run the tests.
cd build ctest -VV
Windows / Visual Studio 2017
Open the Visual Studio 2017 developer command prompt. Create .sln and .vcxproj files and build the static library and tests as follows.
mkdir build cd build cmake -DBoost_INCLUDE_DIR=<boost directory> .. msbuild ALL_BUILD.vcxproj
Run the tests.
cd build ctest -C debug
More on tests
To run the tests outside of CTest you will need to provide the path to the test cases as an environment variable.
cd build export TEST_DIR=../3rdparty/test_cases/ ./evm_tests
The full test suite contains some longer performance tests which are skipped by default. For full coverage, these can be run by passing the
no-skip option to the test app - these should complete in minutes, while the default tests should complete in under a second.
cd build time TEST_DIR=../3rdparty/test_cases/ ./evm_tests ... real 0m0.424s time TEST_DIR=../3rdparty/test_cases/ ./evm_tests -ns ... real 2m11.306s
Note that the test harness skips several test cases. Some of these test features which are not supported (gas exhaustion, huge address space), while others appear malformed (do not match the documented test format).
We rely on several open source third-party components, attributed under THIRD_PARTY_NOTICES.
The Keccak sources were created from the reference KeccakCodePackage by running
make FIPS202-opt64.pack. Unfortunately, we cannot use the probably more optimized ASM versions for now, because they are neither PIC nor Visual Studio compatible.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repositories using our CLA.