fn transfer<'a, T: Trait, V: Vm<T>, L: Loader<T>>(
	gas_meter: &mut GasMeter<T>,
	cause: TransferCause,
	transactor: &T::AccountId,
	dest: &T::AccountId,
	value: BalanceOf<T>,
	ctx: &mut ExecutionContext<'a, T, V, L>,
) -> Result<(), &'static str> {
	use self::TransferCause::*;
	use self::TransferFeeKind::*;

	let to_balance = ctx.overlay.get_balance(dest);

	// `would_create` indicates whether the account will be created if this transfer gets executed.
	// This flag is orthogonal to `cause.
	// For example, we can instantiate a contract at the address which already has some funds. In this
	// `would_create` will be `false`. Another example would be when this function is called from `call`,
	// and account with the address `dest` doesn't exist yet `would_create` will be `true`.
	let would_create = to_balance.is_zero();

	let token = {
		let kind: TransferFeeKind = match cause {
			// If this function is called from `Instantiate` routine, then we always
			// charge contract account creation fee.
			Instantiate => ContractInstantiate,

			// Otherwise the fee depends on whether we create a new account or transfer
			// to an existing one.
			Call => if would_create {
				TransferFeeKind::AccountCreate
			} else {
				TransferFeeKind::Transfer
			},
		};
		TransferFeeToken {
			kind,
			gas_price: gas_meter.gas_price(),
		}
	};

	if gas_meter.charge(ctx.config, token).is_out_of_gas() {
		return Err("not enough gas to pay transfer fee");
	}

	// We allow balance to go below the existential deposit here:
	let from_balance = ctx.overlay.get_balance(transactor);
	let new_from_balance = match from_balance.checked_sub(&value) {
		Some(b) => b,
		None => return Err("balance too low to send value"),
	};
	if would_create && value < ctx.config.existential_deposit {
		return Err("value too low to create account");
	}
	T::Currency::ensure_can_withdraw(transactor, value, WithdrawReason::Transfer, new_from_balance)?;

	let new_to_balance = match to_balance.checked_add(&value) {
		Some(b) => b,
		None => return Err("destination balance too high to receive value"),
	};

	if transactor != dest {
		ctx.overlay.set_balance(transactor, new_from_balance);
		ctx.overlay.set_balance(dest, new_to_balance);
		ctx.events
			.push(RawEvent::Transfer(transactor.clone(), dest.clone(), value));
	}

	Ok(())
}
/// Transfer some funds from `transactor` to `dest`.
///
/// All balance changes are performed in the `overlay`.
///
/// This function also handles charging the fee. The fee depends
/// on whether the transfer happening because of contract instantiation
/// (transfering endowment) or because of a transfer via `call`. This
/// is specified using the `cause` parameter.
///
/// NOTE: that the fee is denominated in `BalanceOf<T>` units, but
/// charged in `T::Gas` from the provided `gas_meter`. This means
/// that the actual amount charged might differ.
///
/// NOTE: that we allow for draining all funds of the contract so it
/// can go below existential deposit, essentially giving a contract
/// the chance to give up it's life.
Transfer some funds from `transactor` to `dest`.
All balance changes are performed in the `overlay`.

This function also handles charging the fee. The fee depends
on whether the transfer happening because of contract instantiation
(transfering endowment) or because of a transfer via `call`. This
is specified using the `cause` parameter.



that we allow for draining all funds of the contract so it
can go below existential deposit, essentially giving a contract
the chance to give up it's life.
Transfer some funds from ` transactor ` to ` dest ` . All balance changes are performed in the ` overlay ` . This function also handles charging the fee . The fee depends on whether the transfer happening because of contract instantiation ( transfering endowment ) or because of a transfer via ` call ` . This is specified using the ` cause ` parameter . that we allow for draining all funds of the contract so it can go below existential deposit essentially giving a contract the chance to give up it ' s life .
fn transfer<'a, T: Trait, V: Vm<T>, L: Loader<T>>(
	gas_meter: &mut GasMeter<T>,
	cause: TransferCause,
	transactor: &T::AccountId,
	dest: &T::AccountId,
	value: BalanceOf<T>,
	ctx: &mut ExecutionContext<'a, T, V, L>,
) -> Result<(), &'static str> {
	use self::TransferCause::*;
	use self::TransferFeeKind::*;
	let to_balance = ctx.overlay.get_balance(dest);
	// `would_create` indicates whether the account will be created if this transfer gets executed.
	// This flag is orthogonal to `cause.
	// For example, we can instantiate a contract at the address which already has some funds. In this
	// `would_create` will be `false`. Another example would be when this function is called from `call`,
	// and account with the address `dest` doesn't exist yet `would_create` will be `true`.
	let would_create = to_balance.is_zero();
	let token = {
		let kind: TransferFeeKind = match cause {
			// If this function is called from `Instantiate` routine, then we always
			// charge contract account creation fee.
			Instantiate => ContractInstantiate,
			// Otherwise the fee depends on whether we create a new account or transfer
			// to an existing one.
			Call => if would_create {
				TransferFeeKind::AccountCreate
			} else {
				TransferFeeKind::Transfer
			},
		};
		TransferFeeToken {
			kind,
			gas_price: gas_meter.gas_price(),
		}
	};
	if gas_meter.charge(ctx.config, token).is_out_of_gas() {
		return Err("not enough gas to pay transfer fee");
	}
	// We allow balance to go below the existential deposit here:
	let from_balance = ctx.overlay.get_balance(transactor);
	let new_from_balance = match from_balance.checked_sub(&value) {
		Some(b) => b,
		None => return Err("balance too low to send value"),
	};
	if would_create && value < ctx.config.existential_deposit {
		return Err("value too low to create account");
	}
	T::Currency::ensure_can_withdraw(transactor, value, WithdrawReason::Transfer, new_from_balance)?;
	let new_to_balance = match to_balance.checked_add(&value) {
		Some(b) => b,
		None => return Err("destination balance too high to receive value"),
	};
	if transactor != dest {
		ctx.overlay.set_balance(transactor, new_from_balance);
		ctx.overlay.set_balance(dest, new_to_balance);
		ctx.events
			.push(RawEvent::Transfer(transactor.clone(), dest.clone(), value));
	}
	Ok(())
}
fn transfer < ' a , T : Trait , V : Vm < T > , L : Loader < T > > ( gas_meter : & mut GasMeter < T > , cause : TransferCause , transactor : & T :: AccountId , dest : & T :: AccountId , value : BalanceOf < T > , ctx : & mut ExecutionContext < ' a , T , V , L > , ) -> Result < ( ) , & ' static str > { use self :: TransferCause :: * ; use self :: TransferFeeKind :: * ; let to_balance = ctx . overlay . get_balance ( dest ) ; // `would_create` indicates whether the account will be created if this transfer gets executed. // This flag is orthogonal to `cause. // For example, we can instantiate a contract at the address which already has some funds. In this // `would_create` will be `false`. Another example would be when this function is called from `call`, // and account with the address `dest` doesn't exist yet `would_create` will be `true`. let would_create = to_balance . is_zero ( ) ; let token = { let kind : TransferFeeKind = match cause { // If this function is called from `Instantiate` routine, then we always // charge contract account creation fee. Instantiate => ContractInstantiate , // Otherwise the fee depends on whether we create a new account or transfer // to an existing one. Call => if would_create { TransferFeeKind :: AccountCreate } else { TransferFeeKind :: Transfer } , } ; TransferFeeToken { kind , gas_price : gas_meter . gas_price ( ) , } } ; if gas_meter . charge ( ctx . config , token ) . is_out_of_gas ( ) { return Err ( " " ) ; } // We allow balance to go below the existential deposit here: let from_balance = ctx . overlay . get_balance ( transactor ) ; let new_from_balance = match from_balance . checked_sub ( & value ) { Some ( b ) => b , None => return Err ( " " ) , } ; if would_create && value < ctx . config . existential_deposit { return Err ( " " ) ; } T :: Currency :: ensure_can_withdraw ( transactor , value , WithdrawReason :: Transfer , new_from_balance ) ? ; let new_to_balance = match to_balance . checked_add ( & value ) { Some ( b ) => b , None => return Err ( " " ) , } ; if transactor != dest { ctx . overlay . set_balance ( transactor , new_from_balance ) ; ctx . overlay . set_balance ( dest , new_to_balance ) ; ctx . events . push ( RawEvent :: Transfer ( transactor . clone ( ) , dest . clone ( ) , value ) ) ; } Ok ( ( ) ) }
Transfer some funds from `transactor` to `dest`.
Transfer some funds from ` transactor ` to ` dest ` .
gas_meter
&mut GasMeter<T>
cause
TransferCause
transactor
&T::AccountId
dest
&T::AccountId
value
BalanceOf<T>
ctx
&mut ExecutionContext<'a, T, V, L>
gas_meter
&mut GasMeter<T>
cause
TransferCause
transactor
&T::AccountId
dest
&T::AccountId
value
BalanceOf<T>
ctx
&mut ExecutionContext<'a, T, V, L>