[Proposal] Precompile to check active precompiles

Precompile to check active precompiles

Hi, I’m Jérémy (nanocryk on GitHub) of the PureStake dev team. I focus mainly on features related to the EVM, including the precompiles.

Summary

This is a proposal to add a new EVM Precompile allowing checking which precompiles are available and detecting when precompiles are phased-out.

Abstract

EVM precompiles allow extending the features of the EVM by having contracts not defined using EVM bytecode but directly in the node code, or in the case of Moonbeam in the Runtime. Ethereum mainet have precompiles only for cryptographic primitives that would be too costly or impossible to perform in bytecode. Moonbeam, being a Substrate-based chain, adds more precompiles allowing interactions with the Substrate world. This means that with the Substrate and Polkadot ecosystem evolving some features will necessarily evolve in backward-incompatible ways, such as the change for Gov1 to Gov2 or future changes in XCM.

The solution proposed is a precompile which allows checking if a given precompile is still supported or not, which can be used by smart contracts to provide an exit strategy to users when a necessary precompile is removed.

New precompile

A new precompile would be introduced with a function isActivePrecompile(address) returns bool that would return true if the address is part of the Runtime PrecompileSet, and false otherwise (for removed precompiles and for non precompiles).

Precompile removal

A precompile would be removed if the functionality it exposes is no longer available in the Runtime. For exemple as Gov1 is progressively being phased-out in favor of Gov2, once Gov1 is entirely removed the current Gov1 Democracy precompile will no longer be able to work, and it is unlikely to make it work with Gov2 without breaking-changes that would affect contracts.

In that case the precompile will be removed and replaced with code that always reverts, and isActivePrecompile will now return false while it returned true before. The precompile for Gov2 would be deployed on a different address for new contracts to use it.

Impact for smart contract developers

The introduction of this precompile is not in itself a breaking change. Currently deployed contracts are not affected. Newly deployed contracts however should use this new precompile to allow its users to have a clear exit path in case the precompile the contract is relying on is removed, without the need for an admin to intervein. Contracts implemented with the proxy design can update their implementation to allow the same thing.

Here is an exemple of how to use this precompile:

interface IActivePrecompiles {
    function isActivePrecompile(address precompileAddress)
        external view returns (bool);
}

interface IDemocracy {
    function second(uint256 propIndex, uint256 secondsUpperBound) external;
}

contract Exemple {
    IActivePrecompiles constant ACTIVE_PRECOMPILES = IActivePrecompiles(/* TODO: Address*/);
    IDemocracy constant DEMOCRACY = IDemocracy(0x0000000000000000000000000000000000000803);
    
    bool public enabled = true;

    modifier isEnabled() {
        require(enabled, "Contract is now disabled");
        _;
    }

    modifier isDisabled() {
        require(!enabled, "Contract is not disabled");
        _;
    }

    function someFunction() isEnabled() external {
        // do stuff with the precompile.
        // this will revert if Democracy precompile is removed.
        DEMOCRACY.second(1, 1);
    }

    function exitPath() isDisabled() external {
        // Do something only allowed if the contract has been disabled following
        // precompile removal.
    }

    function disable() external {
        bool active = ACTIVE_PRECOMPILES.isActivePrecompile(address(DEMOCRACY));

        if (!active) {
            enabled = false;
        }
    }
}

Next steps

After a few days of collecting feedback from the Community and if there are arguments against/or new suggestions, a 7 days voting session will take place. Otherwise this idea will be implemented and proposed to be included in one of the following Runtime Upgrades.

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

8 Likes

Hey, Jeremy. first of all, thank you for your work that you are doing!

did I understand correctly that this proposal concerns devs, and this new feature will help smart contracts to find out which precompiles are still available and which are already outdated. thus, if the necessary precompile is removed, smart contracts can provide their users with a way out without needing anyone’s help

2 Likes

I’m a strong supporter of this idea. This will help devs to build safer apps that can recover gracefully when precompiles or the pallets underneath them change.

2 Likes

I agree with this proposal!