[Proposal][Status: Idea] Remote EVM execution for Moonriver and Moonbeam

Remote EVM execution for Moonriver and Moonbeam

My name is Gorka (girazoki) from the Purestake dev team, focusing most of the time on XCM.

Summary

This is a proposal to enable EVM remote execution (i.e., EVM execution triggered by a remote chain) in Moonriver and Moonbeam. The main idea is that we install the EthereumXcm pallet in Moonriver and Moonbeam, which acts as a proxy between the XCM execution and the EVM world.

Abstract

Moonbeam is focused on bringing the best of both the Polkadot ecosystem and the EVM worlds to its users. This implies being able to leverage cross-chain capabilities to offer EVM support to other parachains that are seeking interactions with projects already deploted in Moonbeam.

While XCM is alreay able to trigger remote execution, calling the EVM implies several assumptions that we cannot guarantee through XCM. These include, among others, the fact that we cannot provide a signature and a nonce as we need to dispatch transactions through keyless accounts like the sovereign account.

The solution proposed implies calling a special pallet, called EthereumXCM, with a subset of the arguments that are necessary to call the EVM directly. With this new pallet, other chains from the Polkadot ecosystem will be able to trigger remote EVM execution in Moonbeam and leverage interactions with any of the projects already deployed.

Where are we now?

I will describe the current remote execution status from two different perspectives:

  • Pallets callable remotely: The current status is that the pallets/extrinsics that are callable remotely are those that imply a signed origin. Any other pallet requiring a special origin requires specific conversions that are not in place yet in Moonriver and Moonbeam. This is the case of pallet-ethereum, which requires an EthereumOrigin.
  • Accounts that are able to dispatch remotely: Only the parachains sovereign account is able to dispatch transactions in Moonriver. In order to dispatch transactions through XCM, a specific MultiLocation to dispatchOrigin is required and as of today, its only implemented for the main sovereign account.

What do we need to be able to call the EVM remotely?

In the following I describe the main requirements that are needed to be able to enable remote-EVM calls:

  1. Signature check bypass: Keyless accounts like the sovereign account will not ever be able to provide a signature as there is no private key backing it. This means we need to be able to call the EVM bypassing preliminary signature checks.
  2. Avoid Ethereum Tx hash collision: The signature is part of the transaction hash, and since we no longer have a signature, just trusting the body of the transaction could lead to hash collisions.
  3. Enable multilocation-derived keyless accounts: Having only the possibility of using the main sovereign account limits quite a lot the usecases that can be performed, as it would only allow parachain origins to issue EVM transactions. Thus, we need to be able to derive keyless accounts from locations that are not the parachain locations.
  4. Fee payment: XCM or EVM: Currently the XCM executor and the EVM executor have their own independent ways of charging for fee. In order to prevent double-charging, we need to decide which satisfy our needs better.
  5. Be able to dispatch from a keyed account instead of a keyless account: While for security we cannot dispatch directly XCM transactions from a keyed account, we can allow a user to decide whether it wants to create a proxy between its keyless account and its keyed account.

EthereumXcm pallet

The ethereumXcm pallet provides solution to requirements 1,2 4 and 5. Similar to how pallet-ethereum works, it provides an interface between the XCM-executor and the EVM. This pallet works with a special origin called XcmEthereumTransaction. This origin is only appended when calling the EthereumXcm pallet from the xcm-executor. Thus, we guarantee that this pallet is xcm-callable only.

The pallet also works with the concept of EthereumXcmTransaction. This is a similar type to the one requested by pallet-ethereum:

pub struct EthereumXcmTransactionV2 {
	/// Gas limit to be consumed by EVM execution.
	pub gas_limit: U256,
	/// Either a Call (the callee, account or contract address) or Create (currently unsupported).
	pub action: TransactionAction,
	/// Value to be transfered.
	pub value: U256,
	/// Input data for a contract call. Max. size 65_536 bytes.
	pub input: BoundedVec<u8, ConstU32<MAX_ETHEREUM_XCM_INPUT_SIZE>>,
	/// Map of addresses to be pre-paid to warm storage.
	pub access_list: Option<Vec<(H160, Vec<H256>)>>,
}

However it does not ask for a nonce, gasPrice or signature. This is because:

  • We will use a global nonce as a nonce, that gets incremented everytime we receive an EthereumXcm transaction. This allows to generate different transaction hashes for different EthereumXcm transactions. The global nonce to be used is fetched from the storage Nonce of the EthereumXcm pallet.
  • gasPrice is set to 0 by the pallet because fees will be charged in the xcm-executor, not on the evm executor.
  • signature is not needed as this is an xcm execution. Xcm works with the premise of granting origins permisions to use certain accounts, like the sovereign account.

The pallet contains two main dispatchables:

  • transact(tx: EthereumXcmTransaction): This dispatchable allows to issue a transaction to the evm-executor with the current origin.
  • transact_through_proxy(tx: EthereumXcmTransaction, transact_as: H160): This dispatchable allows to issue a transaction to the evm-executor using transact_as as origin. It requires an ‘Any’ proxy to exist between the transact_as and the current origin.

MultiLocation-derived accounts

As we already said, in order to perform remote calls in the xcm-executor we need to somehow be able to convert a MultiLocation origin to a dispatch Origin, typically defined by a 20-byte account in Moonbeam.

The only conversion that exists today is the Sovereign account conversion. This conversion is performed only for parachain origins, and the associated 20 byte account is constructed by appending together the 'sibl' word, the para_id, and sufficient trailing zeroes.

MultiLocation {parents: 1, interior: X1(Parachain(2000))} -> b'sibl' + b'2000' + trailing zeros.

However, what happens if the origin trying to dispatch is an account on a remote parachain, and not the parachain itself?

MultiLocation {parents: 1, interior: X2(Parachain(2000), AccountKey32(Alice))}

In this case we dont have any conversion do a dispatchOrigin. For this reason we enable the Account20Hash conversion, which basically performs a blake2_256 hash and takes the lowest 20 bytes:

MultiLocation {parents: 1, interior: X2(Parachain(2000), AccountKey32(Alice))} -> blake2_256(MultiLocation {parents: 1, interior: X2(Parachain(2000), AccountKey32(Alice))})[0..20]

This allows Alice in parachain 2000 to have a unique keyless account from which she can dispatch remote transactions in Moonbeam. Note that if a Alice uses the same private key from another chain, her keyless account will be different

Why cannot we directly use Alice?

This is a question that we often get when explaining remote EVM execution. The reason why we cannot use Alice directly to dispatch is because that allows the remote chain to use any account that exists in the Moonbeam ecosystem.

Suppose a malicious chain sends a message claiming it was sent by “Bob” from its chain. “Bob” never sent that message, but still, the malicious chain would be able to act on his behalf on the Moonbeam chain.

With hash-based multilocation derived accounts, a malicious chain can only control those accounts that can be hashed with its para_id. Thus, it cannot target a specific account in Moonbeam, neither can mess with the derived accounts from other chains

Overall picture after this change

After this change, there will be two fundamental ways of entering the EVM executor:

  1. Through the regular frontier RPC interface, in which users send signed transactions and all ethereum validations(nonce, gasPrice, signature) are checked.
  2. Through the xcm-executor and EthereumXcm pallet.

Security considerations

It is critical to understand the security implications of this schema. Here are the main points to take into account:

  • The multilocation derived address is an address controlled by the remote chain. This means that access to such account can be prevented by the remote chain. It also means that a compromised chain can act on your behalf using this account. For such reason, we recommend not to treat this account as a private-key backed account. This account should only hold sufficient balance to perform remote interactions, but ideally nothing that would put large amounts of funds at risk.
  • The proxy made from a private key backed account to the multilocation derived address (e.g., Alice->ml_derived_account) is totally up to the user, but it means that if the remote chain gets compromised, such chain would have access the private key backed account on Moonbeam. If such proxy is created, the user is fully trusting the remote chain not to tamper with its account.
  • A full audit on this proposal will be conducted before the code reaches Moonriver and Moonbeam

Key learnings from the Moonbase alpha testnet deployment

There are a couple of important points we have understood from the deployment already made to the Moonbase chain:

  1. Remote EVM interactions are capped itself by the remote execution limits. This means that remote EVM interaction is probably not well-suited for high-demanding EVM executions, as the block space reserved for XCM is limited.
  2. It is critical that other chains have a notion of the fee costs, weight and address derivation mechanics. To help with this, we provided a xcm-utils precompile at address 0x000000000000000000000000000000000000080C. Such precompile will also be available in Moonriver and Moonbeam if this proposal gets accepted

Next steps

A snapshot voting session has been opened for 7 days here : Snapshot Voting

If the snapshot vote passes, this idea will be implemented and proposed to be included in one of the following Runtime Upgrade.

If you have any questions or comments, feel free to reply in the comment section below.

4 Likes

Hey, girazoki. thank you very much for this proposal. we really appreciate your work and your time!

Based on my experience of constant communication with the community, it is always easier for an ordinary non-technical user to perceive information if some simple example of a use case is given.
Сould you please give one simple example of what opportunities would open up for users if this proposal had already entered into force?

I’m guessing the audit was completed since this is moving forward? Is the report public?

While, this is extremely exciting and innovative I wonder why this isn’t being implemented in a phased approach. What is the point of Moonriver if it’s not used to test this functionality first?

Hey turrizt, yes of course! In general it will allow any parachain to be able to interact with any of the smart contracts deployed in Moonriver/Moonbeam.

It’s hard to put ourselves in the scenario of what developers should build, but you can imagine that parachains will have now remote access to, e.g., DEXs, NFTs, liquid staking protocols deployed in Moonriver/Moonbeam, just to name a few.

1 Like

Hey 0xTaylor, thanks for your questions!

The code was shipped to our public testnet Moonbase and its audit has not been completed yet. You can try it out there if you are interested in this feature. You can also gather more information about its deployment here.

However note that there might be some small changes that need to be made for the Moonriver and Moonbeam implementations. We are now asking the community for feedback on this idea going into those network. But that does not mean that the audit has completed yet for the code that will go into those two runtimes, nor the final pieces of the implementation.

Even though the proposal includes both Moonriver and Moonbeam runtimes, it does not imply it will go into both networks at the same time. We are asking the community to express their opinion on pushing this code into both runtimes, but as always, there is a timeframe in which things get deployed in Moonriver before they are deployed in Moonbeam, giving us some testing time to check whether everything is alright. The dates have not yet been discussed, but we always follow a chronology in which features are tested first in Moonriver.

Thank you, Gorka, appreciate your answer. I definitely vote For this proposal!

Hello @girazoki
Great idea, I support your proposal.