As a former Ethereum developer, this challenge was the perfect test of my knowledge to a new and exciting problem. I have been developing on EOSIO for over 2 years now, and the progress of development in the software base continues to amaze me. The recent advancements of EOSVM have been crucial in the development of eosio.evm and the fast execution times achieved by this rendition of the EVM.
What it does
eosio.evm is a Ethereum virtual machine inside the EOSIO WASM virtual machine (VMception!)
It supports all opcodes as specified in the Ethereum Yellow Paper, and those not in the paper yet (introduced in Istanbul Hard Fork), such as SHL Shift left, SHR Shift Right and SAR int256 shift right.
On a fast machine running EOSIO 2 with EOSVM and OC settings, it can execute entire ERC20 contract deployment + initialization + signature recovery in just 750μs, and ERC20 transfers in 500μs
How I built it
eosio.evm is built using the EOSIO Contract Development Kit (CDT), with testing done in both the EOSIO Native Tester suite and JS tests.
The main five stages for the development of the EVM consisted of:
- Support for EOSIO actions/tables
- Opcode support (matching Istanbul HF)
- REVERT support (full exception handling without eosio::check)
- Testing harness and validation testing
Challenges I ran into
The two largest challenges faced in the development of eosio.evm were:
1: Support for recovering Ethereum addresses from Ethereum signatures (v,r,s) was challenging due to the lack of support for decompressing ECC keys in EOSIO. This challenge was overcome by importing a select few functions from the uECC open-source library. In the future, I look forward to EOSIO supporting intrinsics for the decompression of public keys!
2: REVERT opcode support. As described by the Ethereum Yellow paper, all sub-actions in transactions can revert to their original state through the use of the REVERT opcode. In EOSIO, an exception reverts all actions and state changes within the transaction. To overcome this challenge, eosio.evm uses a robust error management system, which ensures no usage of eosio::check after the transaction has been validated and nonce has been incremented.
Accomplishments that I'm proud of
- 100% Success on Ethereum Transaction Tests
- 100% Success on Ethereum RLP Tests
- REVERT support (challenging on EOS as it requires no use of eosio::check after nonce increment)
- Istanbul support
- Full gas cost calculations (not billed to sender)
- Web3-similar call support (query view functions with no state modifications)
- Total size less than 200KB (~2MB on-chain)
- All transactions under 1ms with super-fast machine and eos-vm-oc
What I learned
This challenge has pushed me to learn the Ethereum Virtual Machine inside out, including scouring through dozens of EIPs and previous implementations to develop a deep understanding of the EVM. My understanding of EOSIO has further solidified, building my largest contract to date and applying innovative techniques such as eosio exceptions to emulate Ethereum Web3 calls.
What's next for eosio.evm
- eosio.evm will soon support all precompile contracts currently deployed on Ethereum, currently waiting for ec_mul and ec_add to be added to EOSIO intrinsics
- further validation from state tests in ethereum/tests
- explore experimental support for IBCTRANSFER and IBCBALANCE opcode to transfer EOSIO balance directly from EVM execution