diff --git a/substrate/srml/evm/src/lib.rs b/substrate/srml/evm/src/lib.rs index 37e09eb26436225fb3ef36598bef81c59c80856c..30835986e20143ac9f364aeb5c007122b6962190 100644 --- a/substrate/srml/evm/src/lib.rs +++ b/substrate/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<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance; @@ -117,12 +120,13 @@ decl_module! { fn deposit_balance(origin, value: BalanceOf<T>) -> 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::<u128>::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::<u128>::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<T: Trait> Module<T> { + /// 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);