diff --git a/srml/evm/src/lib.rs b/srml/evm/src/lib.rs index 37e09eb264362..30835986e2014 100644 --- a/srml/evm/src/lib.rs +++ b/srml/evm/src/lib.rs @@ -27,13 +27,16 @@ use rstd::vec::Vec; use support::{dispatch::Result, decl_module, decl_storage, decl_event}; use support::traits::{Currency, WithdrawReason, ExistenceRequirement}; use system::ensure_signed; +use sr_primitives::ModuleId; use sr_primitives::weights::SimpleDispatchInfo; -use sr_primitives::traits::UniqueSaturatedInto; +use sr_primitives::traits::{UniqueSaturatedInto, AccountIdConversion}; use primitives::{U256, H256, H160}; use evm::{ExitReason, ExitSucceed, ExitError}; use evm::executor::StackExecutor; use evm::backend::ApplyBackend; +const MODULE_ID: ModuleId = ModuleId(*b"py/ethvm"); + /// Type alias for currency balance. pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; @@ -117,12 +120,13 @@ decl_module! { fn deposit_balance(origin, value: BalanceOf) -> Result { let sender = ensure_signed(origin)?; - T::Currency::withdraw( + let imbalance = T::Currency::withdraw( &sender, value, WithdrawReason::Reserve.into(), - ExistenceRequirement::KeepAlive, + ExistenceRequirement::AllowDeath, )?; + T::Currency::resolve_creating(&Self::account_id(), imbalance); let bvalue = U256::from(UniqueSaturatedInto::::unique_saturated_into(value)); let address = T::ConvertAccountId::convert_account_id(&sender); @@ -139,15 +143,20 @@ decl_module! { let address = T::ConvertAccountId::convert_account_id(&sender); let bvalue = U256::from(UniqueSaturatedInto::::unique_saturated_into(value)); - if Accounts::get(&address).balance < bvalue { - return Err("Not enough balance to withdraw") - } + let mut account = Accounts::get(&address); + account.balance = account.balance.checked_sub(bvalue) + .ok_or("Not enough balance to withdraw")?; - Accounts::mutate(&address, |account| { - account.balance -= bvalue; - }); + let imbalance = T::Currency::withdraw( + &Self::account_id(), + value, + WithdrawReason::Reserve.into(), + ExistenceRequirement::AllowDeath + )?; + + Accounts::insert(&address, account); - T::Currency::deposit_creating(&sender, value); + T::Currency::resolve_creating(&sender, imbalance); Ok(()) } @@ -256,6 +265,14 @@ decl_module! { } impl Module { + /// The account ID of the EVM module. + /// + /// This actually does computation. If you need to keep using it, then make sure you cache the + /// value and only call this once. + pub fn account_id() -> T::AccountId { + MODULE_ID.into_account() + } + /// Check whether an account is empty. pub fn is_account_empty(address: &H160) -> bool { let account = Accounts::get(address);