rustethereumsubstrateparity-ioevm

How to implement the EVM Trait for a Substrate Runtime?


Following the adding a module to your runtime, I'm trying to implement the Parity Substrate paint-evm trait for the Dothereum Runtime.

The EVM module trait is defined as follows:

pub trait Trait: Trait + Trait {
    type FeeCalculator: FeeCalculator;
    type ConvertAccountId: ConvertAccountId<Self::AccountId>;
    type Currency: Currency<Self::AccountId>;
    type Event: From<Event> + Into<Self::Event>;
    type Precompiles: Precompiles;
}

The adding a module tutorial here, however, is a bit vague and encourages one to:

".. explore the source code of the [..] module if things don't make sense .."

While the EVM module code doesn't seem too complex, I fail to understand how to implement the EVM trait for my runtime:

impl evm::Trait for Runtime {
    type FeeCalculator = ();
    type ConvertAccountId = ();
    type Currency = Balances; 
    type Event = Event;
    type Precompiles = ();
}

What types do FeeCalculator and ConvertAccountId expect here?


Solution

  • Because pallet-evm doesn't provide default implementations for the types you need, you'll need to create them yourself.

    use paint_evm::{FeeCalculator, ConvertAccountId};
    use primitives::{U256, H160};
    
    pub struct FixedGasPrice;
    
    impl FeeCalculator for FixedGasPrice {
        fn gas_price() -> U256 {
            // Gas price is always one token per gas.
            1.into()
        }
    }
    
    pub struct TruncatedAccountId;
    
    impl<AccountId> ConvertAccountId<AccountId> for TruncatedAccountId {
        fn convert_account_id(account_id: &AccountId) -> H160 {
            //TODO just truncate the fist several bits and return the resulting H160
            // Or maybe hashing is easier to figure out
            unimplemented!();
        }
    }
    
    impl paint_evm::Trait for Runtime {
        type FeeCalculator = FixedGasPrice;
        type ConvertAccountId = TruncatedAccountId;
        type Currency = Balances;
        type Event = Event;
        type Precompiles = (); // We can use () here because paint_evm provides an
                               // `impl Precompiles for ()``
                               // block that always returns none (line 75)
    }
    

    I look forward to improving this answer as I understand more myself.