ERC-1132: 通过代币锁定功能扩展 ERC20
Authors | nitika-goel <nitika@govblocks.io> |
---|---|
Created | 2018-06-03 |
Discussion Link | https://github.com/ethereum/EIPs/issues/1132 |
Table of Contents
简单总结
通过在合约中进行代币时间锁定的方法来扩展 ERC20 标准。
摘要
本提案提供了基本功能,用于在 ERC20 智能合约中对代币进行时间锁定,以实现多种效用,而无需将代币转移到外部托管智能合约。它还允许获取锁定和可转让代币的余额。
时间锁定也可以通过 staking (#900) 实现,但这需要将代币转移到托管合约/ stake manager,从而导致以下六个问题:
- 对托管合约/ stake manager 的额外信任
- 代币转移的额外审批流程
- 由于转移中的 gas 需求而增加运营成本
- 糟糕的用户体验,因为用户需要从外部托管处取回金额
- 用户无法跟踪其真实的代币余额/代币活动
- 用户无法在代币生态系统中使用其锁定的代币。
动机
dApp 通常需要对代币进行时间锁定,以防止转移,从而让成员 1) 遵守归属计划,以及 2) 展示利益相关性,以符合底层业务流程。我在构建 Nexus Mutual 和 GovBlocks 时意识到了这种需求。
在 Nexus Mutual 中,索赔评估员需要锁定他们的代币,然后才能对索赔评估进行投票。这很重要,因为它确保了评估员的利益相关性。这里的需求是,一旦索赔评估员将其代币锁定 ‘n’ 天,他应该能够在 ‘n’ 天内进行多次投票,这对于 staking 机制来说是不可行的。还有其他场景,如技能/身份验证或参与游戏化的代币管理注册表,也需要时间锁定的代币。
在 GovBlocks 中,我想允许 dApp 锁定成员代币以进行治理,同时仍然允许成员将这些锁定的代币用于 dApp 业务中的其他活动。DGX 治理模型也是如此,他们已经提议每季度锁定代币,以参与 DGX 的治理活动。
除了锁定功能外,我还提出了一个 Lock()
和 Unlock()
事件,就像 Transfer()
事件一样,用于跟踪代币锁定和解锁状态。从代币持有者的角度来看,如果某些代币被转移到另一个帐户进行锁定,则很难管理代币持有量,因为每当在代币持有者的帐户上触发 balanceOf()
查询时,结果不包括锁定的代币。totalBalanceOf()
函数旨在解决这个问题。
本提案的目的是通过代币锁定功能增强 ERC20 标准,以便 dApp 可以对成员的代币进行时间锁定,而无需将代币转移到托管/ stake manager,同时允许成员将锁定的代币用于多种效用。
规范
我对 ERC20 接口进行了以下增强:
锁定代币
/**
* @dev 锁定针对特定地址的指定数量的代币,
* 基于指定的原因和时间
* @param _reason 锁定代币的原因
* @param _amount 要锁定的代币数量
* @param _time 锁定时长,以秒为单位
*/
function lock(bytes32 _reason, uint256 _amount, uint256 _time) public returns (bool)
获取在每个实用程序下锁定的代币数量
/**
* @dev 返回为指定地址锁定的代币,
* 基于指定的原因
*
* @param _of 要查询锁定代币的地址
* @param _reason 查询锁定代币的原因
*/
tokensLocked(address _of, bytes32 _reason) view returns (uint256 amount)
获取在未来时间戳下每个实用程序下锁定的代币数量
/**
* @dev 返回为指定地址锁定的代币,
* 基于指定的原因,在特定时间
*
* @param _of 要查询锁定代币的地址
* @param _reason 查询锁定代币的原因
* @param _time 查询锁定代币的时间戳
*/
function tokensLockedAtTime(address _of, bytes32 _reason, uint256 _time) public view returns (uint256 amount)
获取地址持有的代币数量
/**
* @dev @dev 返回地址持有的总代币数量(锁定 + 可转让)
* @param _of 要查询总余额的地址
*/
function totalBalanceOf(address _of) view returns (uint256 amount)
延长锁定期
/**
* @dev 延长基于指定原因和时间的锁定
* @param _reason 锁定代币的原因
* @param _time 锁定延长时长,以秒为单位
*/
function extendLock(bytes32 _reason, uint256 _time) public returns (bool)
增加锁定的代币数量
/**
* @dev 增加基于指定原因锁定的代币数量
* @param _reason 锁定代币的原因
* @param _amount 要增加的代币数量
*/
function increaseLockAmount(bytes32 _reason, uint256 _amount) public returns (bool)
获取在每个实用程序下可解锁的代币数量
/**
* @dev 返回为指定地址锁定的可解锁代币,基于指定原因
* @param _of 要查询可解锁代币数量的地址
* @param _reason 查询可解锁代币的原因
*/
function tokensUnlockable(address _of, bytes32 _reason) public view returns (uint256 amount)
获取可解锁的代币数量
/**
* @dev 获取指定地址的可解锁代币
* @param _of 要查询可解锁代币数量的地址
*/
function getUnlockableTokens(address _of) public view returns (uint256 unlockableTokens)
解锁代币
/**
* @dev 解锁指定地址的可解锁代币
* @param _of 声明取回可解锁代币的用户的地址
*/
function unlock(address _of) public returns (uint256 unlockableTokens)
记录在代币合约中的锁定事件
event Locked(address indexed _of, uint256 indexed _reason, uint256 _amount, uint256 _validity)
记录在代币合约中的解锁事件
event Unlocked(address indexed _of, uint256 indexed _reason, uint256 _amount)
测试用例
测试用例可在 https://github.com/nitika-goel/lockable-token 获得。
实现
- 完整实现可在 https://github.com/nitika-goel/lockable-token 获得
- GovBlocks 项目特定实现可在 https://github.com/somish/govblocks-protocol/blob/Locking/contracts/GBTStandardToken.sol 获得
版权
通过 CC0 放弃版权和相关权利。
Citation
Please cite this document as:
nitika-goel <nitika@govblocks.io>, "ERC-1132: 通过代币锁定功能扩展 ERC20 [DRAFT]," Ethereum Improvement Proposals, no. 1132, June 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1132.