Staking
总览
Conflux引入权益质押机制的原因有两个:一、权益机制提供了一种对占用存储空间更好的收费方式(相比于“一次付费,永久占用”)。二、该机制还有助于定义分散治理中的投票权。
在顶层,Conflux实现了一个内置的Staking合约,以记录所有账户的权益信息。通过向该合约发送交易,用户(包括外部用户和智能合约)可以存入/提取资金,也被称为合约内的权益。
用户可以通过调用 deposit(uint amount)
来存入用于抵押的金额,随后 amount
数量的资金将从其 balance
移至 stakingBalance
. 需要注意的是该函数不是 payable
的,用户只需要指定抵押的金额而无需将资金转入到内部合约中。
用户还可以通过调用 withdraw(uint amount)
来提取余额。调用者可以调用该函数从Conflux质押合约提取部分代币。抵押资金将会及时的转入用户余额中。所有提款的顺序将按照先到先服务的方式进行处理。
锁定与投票权
通过锁定质押余额,用户可获取投票权以进一步进行链上治理。通过调用 voteLock(uint amount, uint unlock_block_number)
函数,一个帐户可以做出如下承诺:“我的 stakingBalance
在未来 unlock_block_number
中将始终具有至少 amount
的资金”。单个账户可以做出多个承诺,比如说“今年我将至少持有10CFX,并且在明年至少持有5CFX。” **一旦做出承诺,无法取消!**但是该账户可通过锁定更多的金额覆盖原有的承诺。每当账户尝试提取 stakingBalance
时,内部合约会检查剩余余额是否与锁定承诺吻合。
在此处我们将通过几个样例介绍锁定余额的逻辑细节。假设Conflux在今年的剩余时间将产生 x
个区块,在明年的产生 y
个区块。由于Conflux网络每秒能生成两个区块,因此 y
近似等于 2 * 60 * 60 * 24 * 365
。而 x
取决于您何时阅读到该文章。
- 假设一个账户的
stakingBalance
中有10CFX,如果其调用voteLock(100 * 10^18, x)
,说明账户尝试锁定 100CFX. 但由于其缺少足够的stakingBalance
,交易执行失败。 - 然而,如果该账户调用
voteLock(8 * 10^18, x)
,则交易会成功。 - 随后,如果该账户调用
voteLock(6 * 10^18, x+y)
,交易同样会成功。这意味着交易执行后 2CFX 在今年结束时解锁,而另外 6CFX 会被锁定直到明年结束。 - 如果账户再调用
voteLock(0, x)
,没有任何事情会发生。在交易执行过程中交易不会触发错误。内置合约会将此调用视为无意义的承诺:该帐户在步骤 2、3 做出的旧承诺有效的前提下,再次承诺在今年结束前至少锁定 0 CFX. - 如果该账户调用
voteLock(9 * 10^18, x+y)
,则两个较老的承诺将会因为“锁定 9CFX 直到明年结束是一个更强的承诺”被覆盖。
锁定对利息无任何影响。当账户成功取出抵押余额时,利息会将照常计算。
在任何时间,每一个锁定的金额将根据其解锁时间被分配0到1的表决权。锁定期超过1年的部分将拥有全额的投票权利。查看 Conflux Protocol Specification 章节 8.3.2 获取更多信息。
样例
const PRIVATE_KEY = '0xxxxxxx';
const cfx = new Conflux({
url: 'http://test.confluxrpc.org',
logger: console,
});
const account = cfx.wallet.addPrivateKey(PRIVATE_KEY); // create account instance
const staking_contract = cfx.InternalContract('Staking');
// deposit some amount of tokens
staking_contract.deposit(your_number_of_tokens).sendTransaction({
from: account,
}).confirmed();
// withdraw some amount of tokens
staking_contract.withdraw(your_number_of_tokens).sendTransaction({
from: account,
}).confirmed();
// lock some tokens until some block number
staking_contract.voteLock(your_number_of_tokens, your_unlock_block_number).sendTransaction({
from: account,
}).confirmed();
No Comments