Here is a scheme for categorizing Ethereum compatibility for some given blockchain. The key is to assess the layers of Program Equivalence:
- Level 0: Full compatibility (Essentially a chain code fork)
- Level 1: Bytecode level compatibility
- Level 2: Code compile-level language compatibility (Eg. Solang)
- Level 3: RPC/endpoint extrinsic compatibility (Eg. Ability to sign using Metamask / Ability to read data using the same block explorers)
pallet-ethereum already provide Level 0 compatibility to Substrate, there’s instances where we might prefer native Substrate execution over Frontier’s SputnikVM Runner, as a workaround to its inherent performance penalties. So we want to be able to navigate this scheme as a spectrum of compatibility with legacy EVM standards.
The easiest place to start is at Level 3. From there, climbing up the compatibility levels implies that things can go in a couple different directions, namely:
- EVMless Execution: Re-routing Eth RPCs for native Subtrate execution under multiple FRAME pallets.
Wasm Contract Execution: Re-routing Eth RPCs for execution under
I recently learned about a community effort that is apparently being called
WrappedEVM, including teams like Interlay, Centrifuge and HydraDX. So I’m starting this thread as a way to coordinate those efforts.
EVMless Execution (
dispatch precompile is made available by
pallet-evm. It an obvious initial step in this direction, as it opens up the possibility of triggering FRAME execution via Eth RPCs. It is already available and a really low-hanging-fruit for teams aiming to go down this route.
It is still a bit cumbersome, however, because the RPC side is still partially “contaminated” with Substrate, as it requires the actual FRAME calls to be SCALE encoded.
For some cases, we might want the Eth RPCs to believe they’re interacting entirely with an EVM ABI, while staying completely agnostic in regards to the Substrate realm. This starts from the assumption that there are already pallets deployed into the Runtime that are able to cover for all the expected functionality that the ABIs expose.
This would require some mechanism for the Runtime to receive the EVM dispatchables and re-route them for native Substrate execution. This can be achieved with a stripped down version of
pallet-evm (let’s call it
pallet-evmless), that provides a simplified EVM shell Runner. Then, for each
Solidity use-case, different precompiles would be written ad-hoc, either tighly or loosely coupling with the pallets responsible for execution. Unique’s
evm-coder crate can be leveraged here so that developers can focus on writing their precompile logic in Rust without worrying too much about the low-level ABI details.
Ideally, we should standardize
pallet-evmless as a new upstream feature on
Note: I’m using the term
EVMless to describe this specific path of action, while
WrappedEVM is being used as the umbrella term for the overall initiative (which also includes the
pallet-contracts path described below).
Wasm Contract Execution (
While still a WIP, there’s a few tools in our community that have great potential to onboard
Solidity devs into Substrate:
Maintained by Unique Network,
evm-coder is a Rust library for seamless call translation between Rust and Solidity code. Not only it can be quite helpful writing precompiles based on
Solidity contracts (on the
EVMless context described above), but it can also be used while writing
ink! contracts as well.
Sol2ink is able to parse compilable
Solidity interfaces into ink! traits and compilable
Solidity contracts into ink! contracts, while leveraging the power of OpenBrush. The effort is led by SuperColony, but the repository seems stale for the past few months at the time of writing.
Maintained by the HyperLedger Foundation,
Solang is a
Solidity compiler for Solana (which we don’t really care about here) and Substrate. It is able to compile
Solidity contracts for execution under
pallet-contracts. The project is under active development, with frequent contributions from Parity’s Core Engineering.
Be it some
- transpiled to
ink!and then compiled into
- compiled straight into
While deploying them into
pallet-contracts, we might want to still interact with them via Eth RPCs. This would imply new features being added into
pallet-contracts. While theoretically feasible, there might be a few challenges to be tackled along the way:
ABI compatibility: currently,
Solangare not following the EVM ABI calling conventions. Making this happen (if even possible) would imply changing the
Solangcalling conventions, which opens a pandora box of breaking changes between different versions and can be seen as tabu. There’s also the problem that the
Wasmcontracts use types as arguments and return values that don’t exist in the EVM ABI. In this case we would probably just specify them as as bytes and live with the fact that a Dapp needs custom code to encode/decode them. Bottom line is: this topic needs more research.
Edit: as added by @lach in comment below ,
evm-coder can potentially help solve some of these issues of ABI compatibility for
- EVM tooling compatibility: Tooling might inspect the code. It might be as little as checking for some magic byte and as sophisticated as generating constructor code. It doesn’t matter if it is just a trivial check. That tool will not work as we will be feeding it wasm code. We would need to try to upstream compatibility fixes for the tooling projects.
Contract creation: A contract running on
pallet-contractscontains a dedicated “construction” entry point. When creating a new contract, input data to is passed to this constructor as data in the transaction. This is different from EVM, where the code passed as data is the constructor itself. There are certainly some ways so work around this but it will require
Soliditydevelopers to do things slightly different from what they are used to.
So there will likely be no perfect on-size-fits-all solution, and we will have to deal with fragmentation at some point. Which is arguably unavoidable, as we can already see in some Eth L2s breaking EVM bytecode and RPC compatibility (e.g.: zkSync and ERC1167).
Nevertheless, this is still a path worth pursuing, as onboarding Ethereum dApps and devs will be really important for the vision of Hybrid Chains in our Ecosystem.