在 Substrate 区块链开发框架中,FRAME Balances 托盘引用了 4 种不同的余额:
- 自由余额
- 预留余额
- 锁定余额
- 归属余额
这些不同类型的天平有什么区别,它们什么时候在 Substrate 中使用,我应该如何在我自己的运行时模块中使用它们?
在 Substrate 区块链开发框架中,FRAME Balances 托盘引用了 4 种不同的余额:
这些不同类型的天平有什么区别,它们什么时候在 Substrate 中使用,我应该如何在我自己的运行时模块中使用它们?
余额模块是一个综合性的链上货币,可以灵活地提供许多不同的功能。
在 Balances 模块的存储中,只有两个直接存储的余额:
这两个余额的总和用于计算帐户的总余额。
额外的逻辑层放置在自由余额之上,以创建抽象,例如:
因此,让我们来看看余额模块管理的不同类型的余额。
从参考文档的术语部分:
自由余额:未保留的余额部分。自由余额是对大多数操作而言唯一重要的余额。当此余额低于现有存款时,该帐户的大部分功能将被删除。当它和保留的余额都被删除时,就说这个账户已经死了。
每当启动transfer
、withdraw
或时,都会使用帐户的可用余额。reserve
在这些操作可以成功完成之前,ensure_can_withdraw
调用一些WithdrawReason
并检查提款不会干扰某些归属余额或锁定余额。
这不会阻止其他操作slash
的发生,它不关心任何对自由余额的抽象。
账户的归属余额是对其自由余额的抽象。更具体地说,具有归属余额的账户不能从低于该金额的自由余额中支出。归属平衡不关心WithdrawReason
。
amount_spendable = free_balance - vesting_balance
因此,即使在查询免费余额时,一个账户看起来有很多流动资金可以使用,但账户归属余额可以防止这些资金被提取。
Vesting balance 只能在 Substrate 链的起源处设置,并以每个块的线性速率减少,从 a 个块开始,starting_block
此时Vesting balancelength
为零。在免费余额因削减而减少的情况下,归属余额可能大于免费余额。在这些情况下amount_spendable
饱和为零。
账户的锁定余额是对其自由余额的另一种抽象。在这种情况下,由于某种原因,一定数量的提款被锁定。
不同的退出原因是:
因此,如果一个账户有 100 个单位的锁定WithdrawReasons::Transfer
,它就不能进行转移,使其自由余额低于 100 个单位。但是,此帐户将能够执行另一项操作,例如reserve
将其免费余额低于 100 个单位。锁定可能有多种相关原因,在这种情况下,这些资金只能用于其他原因。
可以在一个帐户上放置多个不同的锁,但是这些锁相互重叠而不是堆叠。这意味着如果一个账户有 100 个单位的 3 个锁定,该账户可以出于任何原因将其资金花费到 100 个单位,此时锁定将开始发挥作用。
锁定余额也与归属余额重叠,因为这两者是独立检查的,但两项检查都必须通过ensure_can_withdraw
才能成功。
从术语部分:
预留余额:预留余额仍属于账户持有人,但已暂停使用。保留余额仍然可以被削减,但只有在所有免费余额都被削减之后。如果保留的余额低于现有存款,那么它和任何相关功能都将被删除。当它和可用余额都被删除时,则称该帐户已死亡。
相对而言,保留余额比自由余额更简单,因为它没有抽象。从用户那里保留的资金不应该被余额模块之外的任何其他逻辑直接触及。相反,资金应该先unreserved
在free_balance
.
保留余额和锁定余额看起来相似,但本质上是不同的。锁定余额在锁定标识符、资金被锁定的原因以及锁定时间方面具有身份。保留余额没有这些特征,并且如果没有运行时的明确行动来取消保留这些资金,则无法触及。
此外,自由平衡与没有平衡可能会产生影响。例如,如果您对帐户的全部免费余额设置了锁定,它仍然会有免费余额,并且OnFreeBalanceZero
不会被调用。然而,如果你reserve
所有的资金,免费余额将低于现有存款,OnFreeBalanceZero
并将为已实现此功能的模块触发。