名词解释
- Cosmsos Hub - 基于 Tendermint 的 Proof of Stake 区块链系统
- Atom - Cosmsos Hub 原生代币
- Atom holder - Atom 持有者
- Candidate - Validator 候选人,即运行Tendermint全节点,并和其他的Candidate竞选Validator的Atom持有者
- Validator - 验证人,即竞选胜出的 Candidate,负责对 Tendermint 共识中的消息进行签名
- Delegator - 代理人,把自己的Atom代理给一个Validator(或Candidate)的Atom持有者
- Bonding Atoms - 绑定Atom,Atom锁定机制(使Atom受共识协议的控制),Atoms只能通过Validator或Candidate进行绑定,如果Validator作恶,那么他绑定的Atom就会受到损失。如果在一个解绑时限内没有被惩罚,Atom持有者就可以重获对他绑定的Atom的支配权
- Unbonding period - 解绑时限,从解绑操作到Atom持有者重获对这些Atom支配权的一段时间
- Inflationary provisions - 通货膨胀,指增加Atom供给,Cosmos Hub会周期性的创建Atom,并分发给绑定Atom的持有者,目的就是为了鼓励Atom持有者尽量多的绑定他们的Atom
- Transaction fees - 交易费,指包含在一个Cosmos Hub的交易中的手续费,由Validator收集,并根据Validator和Delegator绑定的Atom数量进行分配
- Commission fee - 佣金,Validator 为他所提供的服务从交易费中收取佣金
The pool and the share
Staking 模块的核心概念pool,表示由不同的Atom持有者贡献的Atom的集合,在Staking模块中有两个全局的pool:绑定池(bonded pool)和解绑池(unbonding pool)。绑定的Atom是全局绑定池的一部分。如果一个Candidate或Delegator想要解绑他们的Atom,这些Atom就会先被移动至解绑池,直至达到解绑时限。
pool其实是一个虚拟的概念,就是说在代码中并没有一个叫做pool的数据结构来负责管理pool的资源。所谓的pool实际就是绑定/解绑的Atom总数,或者说是已发放的share总数。
share是Atom分配的一个单位,share的值(share对Atom的汇率)在系统运行的过程中是会发生变化的。share汇率计算公式:
share-to-atom-exchange-rate = size of the pool / ammount of issued shares
这样一来,我们就可以用share为单位,随时计算一个Candidate在pool中拥有的Atom数量:
candidate-coins = candidate.Shares * share-to-atom-exchange-rate
这样的账户模式的优点在于,由 绑定/解绑/惩罚/增发 对pool的修改,只需要修改全局变量(pool 的大小和share的数量),而不会影响 Validator/Candidate 的数据结构。这样比修改每一个Validator的数据要节省很多算力,举个例子:
假设有4个初始的Validator:p1,p2,p3,p4,每个Validator都绑定了10个Atom,然后我们假设初始的share数量是40(初始的share对Atom的汇率可以设置为任意有意义的值,例如share-to-atom-ex-rate = 1,意味着1 share = 1 Atom),那么绑定池的大小是40个Atom,share的数量是40,每个Validator的数据结构中有10个share。现在假如Validator p1又绑定了10个Atom,那么绑定池中的share数和Atom数都会增加到50(汇率没有发生变化),除了全局的变量,这时数据发生修改的对象只有Validator p1的share数量从10变成了20。
假如这时候系统增发了10%的Atom,并添加到了绑定池,那么绑定池的大小就变成了55,而share数量是没有变化的,所以汇率 = 55/50 = 1.1。这时候虽然每个Validator的数据都没有发生变化(p1: 20 shares, p2: 10 shares, p3: 10 shares, p4: 10 shares),但是他们真实的Atom数量却变多了:20 * 1.1 = 22, 10 * 1.1 = 11, 10 * 1.1 = 11, 10 * 1.1 = 11 。
Delegator shares
pool和share的概念作为Staking模块的核心,不只是用于管理全局的pool(包括绑定池和解绑池),还用于Candidate和他的Delegator之间的Atom发放。
对于Candidate来说,绑定Atom到绑定池,得到的是对应的全局pool的shares。但并不是所有的这些Atom都是这个Candidate所拥有的,因为这里还包含其他人代理给这个Candidate的Atom,Candidate和Delegator之间的Atom 和 share 的分发基于delegator shares
的概念。也就是说,每个Candidate都可以发放自定义的delegator shares(Candidate.IssuedDelegatorShares
),相当于这个Candidate所拥有的全局share(Candidate.GlobalStakeShares
)的一部分。delegator shares的规则和全局share是一样的。
再举个例子:
假设有4个初始的Validator:p1,p2,p3,p4,每个Validator都绑定了10个Atom,初始的全局share数量是40:
GlobalState.BondedPool = 40
GlobalState.BondedShares = 40
share-to-atom-exchange-rate = 1
// Candidate data structure of each validator
Candidate.GlobalStakeShares = 10
Candidate.IssuedDelegatorShares = 10
delegator-share-to-global-share-ex-rate = 1 // 全局share对delegator share的汇率
假设这时候一个Delegator d1 代理了 5 个Atom给 Validator p1,那么我们需要改变的数据为:
GlobalState.BondedPool = 45
GlobalState.BondedShares = 45
// Validator p1
Candidate.GlobalStakeShares = 15
Candidate.IssuedDelegatorShares = 15
然后系统增发了5个Atom
GlobalState.BondedPool = 50
除了全局的pool大小,其它的参数都不需要变,这时候share-to-atom-exchange-rate = 50/45,所以Delegator d1现在拥有的Atom:
delegatorCoins = 5 (delegator shares) * 1 (delegator-share-to-global-share-ex-rate) * 50/45 (share-to-atom-ex-rate) = 5.55 Atoms
通货膨胀
通货膨胀对Validator的供给是以每小时为周期的(每小时的第一个区块)。年度增发目标为代币总量的7%到20%。长久的目标是保持增发直至绑定的代币占总量的67%。
年度增发比例会在每个周期开始时重新计算。增发比例会根据当前绑定比例距离期望目标(67%)进行调整。
inflationRateChange(0) = 0
GlobalState.Inflation(0) = 0.07
bondedRatio = GlobalState.BondedPool / GlobalState.TotalSupply
AnnualInflationRateChange = (1 - bondedRatio / 0.67) * 0.13
annualInflation += AnnualInflationRateChange
if annualInflation > 0.20 then GlobalState.Inflation = 0.20
if annualInflation < 0.07 then GlobalState.Inflation = 0.07
provisionTokensHourly = GlobalState.TotalSupply * GlobalState.Inflation / (365.25*24)
因为Validator持有的是一个相对的绑定share,所以当增发时,唯一一个需要修改的值就是 GlobalState.BondedPool
,即每个增发周期:
GlobalState.BondedPool += provisionTokensHourly
参考文档:https://github.com/cosmos/cosmos-sdk/blob/develop/docs/spec/staking/definitions%20and%20examples.md