We present a prototype of a toolchain for compiling Ethereum Virtual Machine (EVM) smart contracts into WebAssembly bytecode for NEAR, and discuss future directions to incorporate this functionality directly into Aurora Engine.
EVM Optimizations in 2021-2022 Changes to NEAR Protocol ● secp256k1 ecrecover host function ● ripemd host function ● alt_bn128 host function ● Decrease in cost per Wasm op code ● Decrease in state access cost (caching trie nodes) ● Increase the per-transaction gas limit Changes to Aurora ● Cache state access ● Optimize for performance instead of code size Changes to SputnikVM ● Implement SIGNEXTEND, MLOAD, and MSTORE more eiciently ● Specialize the PUSH1 and PUSH2 implementations (from generic PUSHN) ● Structure the interpreter loop more eiciently
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.16; contract Calc { function multiply(int a, int b) public pure returns (int) { return a * b; } }
Expensive instructions ● CODECOPY Requires embedding a copy of the original EVM bytecode into the output (bloat) ● PC Requires either instrumenting generated code for precise program-counter accounting (slowdown), or embedding a large lookup table into the output (bloat) ● GAS Requires instrumenting generated code to support precise gas accounting (slowdown) Unimplemented instructions (7) ● CREATE ● CALL ● CALLCODE ● DELEGATECALL ● CREATE2 ● STATICCALL ● SELFDESTRUCT EVM to WebAssembly: Some challenges
Immediately past the MVP release ● Make EVM gas metering optional for a nice speedup when it isn’t required for full EVM compatibility ● Implement a test suite based on popular real-world deployed contracts and associated transactions, sanity checking that for the same inputs we get the same known-good outputs (including EVM gas metering) Future R&D directions past MVP ● Inlining EVM opcode calls for certain instructions where that would benefit ● Applying other standard compiler optimizations from the literature for leaner and meaner bytecode ● Adding NEAR host functions to beer support 256-bit machine words without the need for expensive bigint arithmetic ● Adding NEAR host functions to speed up other aspects of execution, based on extensive and convincing profiling results EVM to WebAssembly: Compiler
Dynamically loaded WebAssembly embedded inside the Aurora Engine (“JIT”) ● Just-in-time compiled WebAssembly bytecode automatically deployed to, stored in, and maintained by the Aurora Engine for “hot” contracts ● Trusted-yet-sandboxed bytecode deployed reproducibly by trusted parties ● Zero EVM compatibility issues, just a significant speedup ● Requires a NEP process, nearcore implementation, and protocol upgrade for dynamic bytecode support (6 months minimum) Standalone static NEAR contract deployment (“AOT”) ● Ahead-of-time compiled WebAssembly bytecode manually deployed on-chain on NEAR, and authenticated with the Aurora Engine registry by the deployer ● Untrusted, arbitrary bytecode deployed directly by third parties ● Some challenges and trade-os for interacting with other EVM contracts (cross-shard calls) ● Doesn’t require anything in particular from NEAR and nearcore EVM to WebAssembly: Execution models