Exploration of a brand-new direction for Polkadot's Ethereum-compatibility layer
This is a symbolic treasury proposal that aims to gather community sentiment regarding a brand-new direction for Polkadot's Ethereum-compatibility layer. It's similar to the expensive referendum track of Wish for Change but only for a specific project (and not the whole network, therefore justifying a lower decision deposit). Due to this being an alternative approach compared with the direction that Parity is currently working on, we first would want to gather some serious opinions from voters, and therefore we think it's important to put this into coin voting to understand how things stand. If passed, beginning in September, we would then start a small treasury proposal for detailed initial work that will likely cost 30k-60k USDC.
This proposal will not replace Parity's Ethereum-compatibility approach that is scheduled on Polkadot Hub (AssetHub), but it's an alternative approach to it. The aim is to avoid the security concerns of Parity's proposal, and to avoid splitting the ecosystem (Polkadot Hub vs. Moonbeam / Acala EVM).
To do this, we aim to utilize the existing work of revmc from Paradigm that compiles EVM bytecode to LLVM, and then target that to PolkaVM. We build the full stack on the existing full Ethereum-compatibility solution of Frontier. This will result in comparable performance with Parity's revive Ethereum-compatibility layer, without the drawbacks described below. This brand-new direction will be a full-compatibility solution, compared with revive's almost-compatibility solution.
With this proposal, we also make sure existing Polkadot parachains are not left behind. As most current Ethereum-compatibility projects uses Frontier in one way or another, this brand-new direction will also be easily deployable to parachains like Moonbeam and Acala.
Background
The many Ethereum-compatibility layers of Polkadot
Ethereum-compatibility on Polkadot has long been in existance. This older project is called Frontier. The on-chain component of pallet-evm
and pallet-ethereum
contain an EVM interpreter that executes EVM bytecode in a full-compatible way. An off-chain component provides compatibility for RPCs. The project has been used in productions for a long time. Current parachains, like Moonbeam and Acala EVM, either directly use Frontier or heavily modify it to suit their own needs. However, as Ethereum-compatibility was not Polkadot's focus, the project was always on the sideline.
In the past two years, the direction of Polkadot's smart contract platform has pivoted, and it was decided that Ethereum-compatibility is one of the main focus. Parity then starts to work on a new Ethereum-compatibility layer. The new architecture is named revive. It consists of an on-chain runtime pallet-revive, the unmodified Solidity compiler solc that compiles Solidity source code to YUL intermediate language, and the resolc compiler that compiles YUL to PolkaVM bytecodes. The new architecture is still in development but is expected to launch later this year according to the public roadmap.
Security in focus
We must not forget why we were on a different direction in the first place and why the choice of Ethereum/EVM was not popular among Polkadot developers. Solidity and EVM were designed in the very early days of the blockchain history. They are, unfortunately, not well designed, and we should not underestimate the security implications of this. As an example, Parity itself was under a massive hack that resulted loss of over 150k ETH (30m USD at that time), directly affecting Polkadot presales. Not to mention all the specification surprises, unnoticed issues till the last minutes that even delayed Ethereum hard forks, as well as some of the more massive hacks (for example, theDAO). All those contributed to Parity's eventual discontinuation of its Parity Ethereum client and disengagement with the Ethereum ecosystem. The unsafety of Solidity and EVM was one of the important reasons why ink/Rust was used for smart contract.
At this moment we're deciding to move back to Ethereum, but we must not forget our expensive past lessons. Embracing Ethereum-compatibility means that security is again on high alert.
The importance of a security-principled approach
It's in the author's opinion that revive, Parity's planned Ethereum-compatibility approach, has safety concerns.
revive uses an "almost-compatibility" approach. The aim is to be able to compile the majority of Solidity source code unmodified, as to encourage users to migrate from Ethereum to Polkadot. Due to the fact that PolkaVM and EVM are different as well as the design differences of revive, the compiler has a large number of documented differences compared with Ethereum.
Being able to compile Solidity source code unmodified to PolkaVM sounds nice on surface. However, as the author has argued in the above section, embracing Ethereum-compatibility means that security must be on high alert. EVM/Ethereum/Solidity is a subtle target, the Javascript of Web3. The problem of them does not often come from lack of security audits -- it's a multi-billion network and the code base often receives sufficient scrutiny. The problem often comes because it makes it easy for users to write unsafe code. Most of the common pitfalls on Ethereum are already well-documented after this many years. However, we're making the same mistake in Polkadot as the early day Ethereum. The codebase of revive can always be audited, but the way users write code on it cannot be fully anticipated in advance. This makes it difficult for even the most experienced security auditors to investigate the consequences of those differences and also how they will interact with existing known pitfalls on Ethereum.
This makes revive's position of being an "almost-compatibility" system, not "full-compatibility", not "some-compatibility", slightly awkward. Some code changes are still occasionally required. Code audits must be redone.
Having those differences also make fuzz testing impossible. For a full-compatibility solution, one can always test all possible cases against another existing implementation until it reaches 100%. However, for an almost-compatibility solution, there will always be a large number of test cases failing attributed to the "known differences".
The essence of the problem is a lack of security-principled approach. The objective is set prematurely (compiling Solidity source code unmodified without a full consideration of what means "unmodified"), and also without a detailed call for review with the ecosystem shareholders and a full look at the desired user experiences.
A split of the ecosystem
The approach of revive also splits Polkadot's Ethereum-compatibility ecosystem into two. The existing parachains like Moonbeam use Frontier. The vast difference in approach makes it difficult for them to adopt or migrate to take advantage of the performance of PolkaVM. We are making Ethereum-compatibility an important focus, but in the mean time we're abandoning "Polkadot-compatibility".
A step back of the strategy
As with everyone else in the Polkadot community, it's also in the author's hope that the new revive Ethereum-compatibility layer can bring a massive inflow of dapp developers to Polkadot. But we also must consider the possibility if this won't be the case and prepare accordingly.
For example, Ethereum core devs, till today, still have the belief that the VM performance is not the main bottleneck. This belief is supported by the benchmarking work of Reth who used EVM-to-LLVM compiler to sync mainnet, and found only 10% performance improvements. In the future, as we have more performance-critical contracts, this may change, but because the dapp developers we attract will come from Ethereum, they may continue to be relauntent. The contract size compiling down to PolkaVM, compared with compiling down to EVM, will be significantly larger. In addition, we're so far not the only chain that has adopted RISC-V in production, and dapps developers may get attracted to them compared with us.
Whether or not our Ethereum-compatibility strategy delivers good results, the bottom line is that our strategy shouldn't hurt us, and it's in the author's opinion that we should never have security as the trade-off. A high-value hack on revive, regardless if we later decide it's purely the dapp developers' fault, is sufficient to kill all the momentum we have built up for PolkaVM, and gives us the label of being another unsafe smart contract platform. We shouldn't let that happen. We shouldn't trade security with performance.
In any case, it's important that we don't rush things. Once smart contracts are deployed, they become immutable. A rushed, but failed deployment is worse than delayed deployment. Whatever our methods are, we should ensure that it won't potentially do harm to Polkadot -- at least we shouldn't expose ourselves to an even more messy situation than Ethereum.
Design
So here enters an alternative approach compared with revive.
revive uses a compiler stack as follows: Solidity -> YUL -> pallet-revive. The new approach in this project uses the compiler stack as follows: Solidity -> EVM -> PolkaVM -> Frontier. The Solidity pipeline becomes entirely unaltered. We compile native Solidity to native EVM bytecode. We then hook up the revmc
project from Paradigm, which is an EVM-to-LLVM recompiler that has successfully synced Ethereum mainnet. This then gives us PolkaVM bytecodes, which is fed into Frontier and use the existing full-compatible system calls.
EVM alongside PolkaVM
In this proposal, we will have EVM alongside PolkaVM. Frontier will still have its EVM interpreter and EVM bytecode will still be interpreted. Alongside with that, a native PolkaVM executor is deployed. This means that we can support all "fallback" cases and still remain full-compatible. Contract creation can either deploy PolkaVM directly (via a new transaction type) or it can still emit EVM bytecode and Frontier will handle everything just fine.
This allows for incremental speed-up that takes into considerations of existing Ethereum smart contracts already on Polkadot. An offchain compiler allows users to compile new contracts from EVM bytecode to PolkaVM and then deploy on-chain with native PolkaVM performance. If something is not possible, there is always the EVM interpreter as fallback.
Code introspection
The main pain point for anything that is not EVM bytecode is code introspection. Because only new contracts will be deployed on-chain in PolkaVM, the issue of code introspection is solvable -- we simply disallow code introspection in the EVM -> PolkaVM compiler. As also discussed in the last section, for any deployed PolkaVM contract, we still allow it to emit EVM bytecode, and in this case we still have the EVM interpreter in Frontier for all fallback cases.
EOF (EVM Object Format)
In this proposal, we anticipate that we'll likely heavily utilize EOF (EVM Object Format). This is a major upgrade on Ethereum that resolves many of the pain points of the existing EVM format. In particular, dynamic jumps are disabled. Bytecode is split into code sections. And code and gas introspection may be disabled. Many important features for EOF support is already well implemented in the toolchains. It's simply that EOF has not yet been deployed in Ethereum mainnet.
By utilizing EOF and compiling EVM to PolkaVM, we will accomplish really close to native speed. Compared with Parity's revive, the goal is also to take possible future Ethereum upgrades into account, but not working on an "independent" solution that will become obsolete in the next few years due to further Ethereum development.
Gas metering and system calls
We utilize PolkaVM native gas metering solution, with certain precautions taken as not to break existing EVM/Solidity invariants.
All system calls are handled by the existing Frontier implementation with production-ready Ethereum compatibility.
Discussions
The goal of this Ethereum-compatibility proposal is to bring a new full-compatibility solution built on Frontier instead of Parity revive's almost-compatibility solution. We also want to make sure the solution, while accomplishing better performance utilizing PolkaVM, does not alienate existing Polkadot ecosystem players like Moonbeam and Acala EVM.
Impact
If this proposal passes, we'll work on a more detailed specification with a treasury proposal in the amount of 30k-60k USDC for the initial work going in the new direction with clearly defined deliverables.
Our vision: an ecosystem that does not work against itself
The revive project is argubly a project built at the expense of its own ecosystem. No matter whether it fulfills the goal of attracting developers from the Ethereum community, one thing is certain -- it will compete with existing parachains like Moonbeam and Acala EVM.
In addition, revive's choice of "almost compatibility" is unfortunately in an awkward spot. Dapp projects must nonetheless be adopted specifically for PolkaVM. Solidity code changes are sometimes needed. Security audits must be redone. And even if a project manages to avoid all of that, the dependencies and build scripts must still be changed.
We therefore have a real risk of an internal split of Polkadot's own ecosystem between Moonbeam/Acala's Ethereum-compatibility and Polkadot Hub's Ethereum-compatibility. This proposal aims to at least partially consolidate that, and brings a viable, and also arguably better solution for everyone, not just for Polkadot Hub.
About
Wei Tang has been deeply involved in Ethereum core dev. He is the author of EIP-2200 as well as several other protocol specifications that are deployed in Ethereum mainnet. He maintains rust-evm
, a Rust Ethereum Virtual Machine implementation. He is also the author and maintainer of Frontier, the current Ethereum-compatibility layer for Polkadot that is used in production by many Polkadot parachains.
FAQ
Have you tried proposing this alternative design to Parity?
Unfortunately due to office politics, this was never possible while the author worked in Parity. Discussions have been sought over the year. On May 19, the author posted in the Polkadot Forum his opinion that almost-compatibility is unsafe. 9 days later on May 28, the author received Parity's letter for termination of employment.
Who is the contact person if I have additional questions but would like to discuss privately?
Please contact Wei Tang ([email protected]).
Comments (1)
was posting this kind of nonsense hiring requirement at EF or have you just completely lost it? this was truly sad read for someone who use to keep you in high regard.
you're actually proposing evm -> pvm -> evm -> frontier?
compile evm to pvm for "native performance", but when code introspection happens, "emit evm bytecode" back and run it through frontier's interpreter? so your optimization disappears the moment anyone calls codecopy?
this is insane. you're building a compiler and decompiler, storing both representations, just to end up back in the interpreter you started with. all to avoid... what? just improving the interpreter directly? or adding a JIT like everyone else?
you warn about Ethereum being a moving target. then propose building on EOF - a spec so unstable Ethereum itself won't deploy it even being widely implemented by client teams. that would be in best case a moving target on top of a moving target, but most likely just another shasper.
funny how you conveniently skip the multiple critical vulnerabilities in frontier. first the DELEGATECALL bug in May 2022 affecting $100M in funds. then the integer truncation vulnerability in June 2022($1M bounty paid). two major security flaws in your code within a month. but sure, lecture us about "security-principled approach" while proposing Rube Goldberg machines built on vaporware.
limiting permissionless programmability is the sole reason nothing permanent has been built on polkadot. contracts pallet should have been everywhere from day one, including even on relay, for those who felt its worth to pay for stability/interaction with staking/governance/identities.