Substrate Balances模块分析
const
- creationFee 1000000000000 // 创建账号的费用,一分钱
- existentialDeposit 100000000000000 // 账号保存的最低存款, 一块钱
- transferFee 1000000000000 // 转账费用,一分钱
Storage
- freeBalance(AccountId): Balance // 账号的自由余额
- locks(AccountId): Vec<BalanceLock> // 被锁定余额的账号
- reservedBalance(AccountId): Balance // 某一账户的对外保留余额;这个仍然可以被惩罚,但是最后被惩罚。
- totalIssuance(): Balance // 整个系统中发行总币额
- vesting(AccountId): Option<VestingSchedule> // 账号的vesting信息
Extrinsics
- forceTransfer(source,dest,value) Exactly as
transfer
,except the origin must be root and the source account may be specified- setBalance(who,new_free,new_reserved) Set the balances of a given account.
- transfer(dest,value) Transfer some liquid free balance to another account.
- transferKeepAlive(dest,value) Same as the [
transfer
] call, but with a check that the transfer will not kill the origin account.
Balacnes模块提供以下方法:
- 获取和设置free balances。
- 索取总的,保留的和未保留的balances。
- 把保留的balances发送回某个存在的受益人账号。
- 在账户间进行balance的转账,当然他们要没有被reserved。
- 惩罚掉一个账号的balance。
- 账号创建和移除。
- 管理总的发行量。
- 设置和管理资产锁。
balances模块的术语:
- Existential Deposit:存现存款,开设或保留账号所需的最低余额,这可以防止“尘埃账号”来填满存储。
- Total Issuance:总发行量,系统中存在的货币的单位总数。
- Reaping an account:通过重置账号来删除账号的行为,在其平衡设置为零之后发生。
- Free Balance:自由余额,余额中没有被保留的部分。自由余额对于大多数操作来说是唯一重要的余额。当自由余额低于存现存款的时候,账号的大部分功能将被移除。当它和保留余额都被删除时,该账号就被认为是死的。
- Reserved Balance:保留余额,保留余额仍属于账号持有人,但已暂停。保留余额仍然可以被惩罚掉,但只有在所有的自由余额都被惩罚掉之后。如果保留余额低于存现存款,那么它和任何相关的功能都将被删除。当它和自由余额都被删除时,这个账号就被认为是死的。
- Imbalance:不平衡,某些资金credited或者debited没有相等或相反的会计平衡(即发行总量和所有账号余额之和之间的差额)的情况。导致不平衡的函数将返回一个可以在运行时逻辑中管理的
Imbalance
的trait对象。(如果不平衡只是简单地减少了,它应该自动保留任何账簿记录,例如发行总额。) - Lock:冻结指定金额的账号自由余额,直到指定的区块号为止。多个锁总是对相同的资金进行操作,所以这些锁“overlay”而不是“stack”。
- Vesting:兑现,类似于锁,这是另外一种情况,但其能够独立的随着时间线性减少流动性约束。
balances实现
Balances模块提供了下面的一些实现traits,如果这些traits提供的方法是开发者需要的,那么开发者就尽量要避免跟Balances模块耦合。
- Currecy:提供处理一个可互换资产的系统。
- ReservableCurrency:处理一个账号中被保留下来的资产。
- LockableCurrency:处理允许流动资金限制的帐户的功能。
- Imbalance:处理在总发行量和账号余额之间出现的不平衡,当创建一个新的资产(例如奖励)或者销毁一些资产(手续费)需要用到这个功能。
- IsDeadAccout:判断一个账号是否用过。
初始化genesis config中设置
/// The total units issued in the system.
pub TotalIssuance get(fn total_issuance) build(|config: &GenesisConfig<T, I>| {
config.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n)
}): T::Balance;
config.vesting.iter().filter_map(|&(ref who, begin, length, liquid)| {
let length = <T::Balance as From<T::BlockNumber>>::from(length);
config.balances.iter()
.find(|&&(ref w, _)| w == who)
.map(|&(_, balance)| {
// Total genesis `balance` minus `liquid` equals funds locked for vesting
let locked = balance.saturating_sub(liquid);
// Number of units unlocked per block after `begin`
let per_block = locked / length.max(sr_primitives::traits::One::one());
(who.clone(), VestingSchedule {
locked: locked,
per_block: per_block,
starting_block: begin
})
})
}).collect::<Vec<_>>()
add_extra_genesis {
config(balances): Vec<(T::AccountId, T::Balance)>;
config(vesting): Vec<(T::AccountId, T::BlockNumber, T::BlockNumber, T::Balance)>;
// ^^ begin, length, amount liquid at genesis
build(|config: &GenesisConfig<T, I>| {
for (_, balance) in &config.balances {
assert!(
*balance >= <T as Trait<I>>::ExistentialDeposit::get(),
"the balance of any account should always be more than existential deposit.",
)
}
});
}
网友评论