Alert Source Discuss
🚧 Stagnant Standards Track: ERC

ERC-1132: 通过代币锁定功能扩展 ERC20

Authors nitika-goel <nitika@govblocks.io>
Created 2018-06-03
Discussion Link https://github.com/ethereum/EIPs/issues/1132

简单总结

通过在合约中进行代币时间锁定的方法来扩展 ERC20 标准。

摘要

本提案提供了基本功能,用于在 ERC20 智能合约中对代币进行时间锁定,以实现多种效用,而无需将代币转移到外部托管智能合约。它还允许获取锁定和可转让代币的余额。

时间锁定也可以通过 staking (#900) 实现,但这需要将代币转移到托管合约/ stake manager,从而导致以下六个问题:

  1. 对托管合约/ stake manager 的额外信任
  2. 代币转移的额外审批流程
  3. 由于转移中的 gas 需求而增加运营成本
  4. 糟糕的用户体验,因为用户需要从外部托管处取回金额
  5. 用户无法跟踪其真实的代币余额/代币活动
  6. 用户无法在代币生态系统中使用其锁定的代币。

动机

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.