如何用Solidity开发一个锁池子智能合约?附代币锁仓的代码与教程

fffmCQ.jpg

如何用Solidity编写一个锁池子智能合约?附代币锁仓开发代码教程

锁池大家都听过,就是将去中心化交易所的流动性资金池锁在智能合约里,短期内拿不出来,这样做的好处是防止项目方跑路。如果你的资金池不锁,大家就会觉得可能会存在风险。现在市场上主流的锁池方式不外乎两种,第一种是直接将LP代币打入黑洞,永久锁池。第二种就是使用粉红锁池、DXlock等第三方平台进行锁池。

关于锁池的详细介绍,可以看我另一篇文章:怎么看BSC薄饼的资金池锁了没有?怎么锁池?

用第三方平台锁池固然方便,但是缺乏安全性。万一锁池平台跑路了怎么办?万一人家那个锁池的合约有漏洞怎么办?基于这个问题,我们可以尝试自己开发一个锁池智能合约,这样既保证了安全性,又可以让用户放心。接下来,就给大家简单讲解一下,如何实现锁池智能合约的开发工作。

锁池合约实现

一、锁池的原理与LP代币的概念

在合约开发之前,我们需要了解一下:锁池的原理是什么,LP代币又是什么东西。

锁池,本质上就是将用户的LP代币锁在智能合约里一段时间,受益人在锁仓期满后可以取走LP代币。那LP代币其实是交易所给出的一个流动性凭证,当用户在去中心化交易所(比如博饼)创建了流动性之后,这个交易所会给予用户一些LP代币作为你撤出流动性的凭证。一旦LP代币被锁住,自然也无法撤出流动性,也就是说池子撤不了了。

二、代码实现锁池合约

下面,我们就写一个锁仓ERC20代币的锁池合约TokenLocker。它的逻辑很简单:

  • 开发者在部署合约时规定锁仓的时间,受益人(锁池人的)地址,以及代币合约。
  • 开发者将代币(或者说LP凭证)转入锁池合约。
  • 在锁仓期满,受益人可以取走合约里的LP代币。

事件

锁池合约中共有2个事件。

  • TokenLockStart:锁仓开始事件,在合约部署时释放,记录受益人地址,代币地址,锁仓起始时间,和结束时间。
  • Release:代币释放事件,在受益人取出代币时释放,记录记录受益人地址,代币地址,释放代币时间,和代币数量。
// 事件
    event TokenLockStart(address indexed beneficiary, address indexed token, uint256 startTime, uint256 lockTime);
    event Release(address indexed beneficiary, address indexed token, uint256 releaseTime, uint256

状态变量

TokenLocker合约中共有4个状态变量。

  • token:锁仓代币地址。
  • beneficiary:受益人地址。
  • locktime:锁仓时间(秒)。
  • startTime:锁仓起始时间戳(秒)。
    // 被锁仓的ERC20代币合约
    IERC20 public immutable token;
    // 受益人地址
    address public immutable beneficiary;
    // 锁仓时间(秒)
    uint256 public immutable lockTime;
    // 锁仓起始时间戳(秒)
    uint256 public immutable startTime;

函数

TokenLocker合约中共有2个函数。

  • 构造函数:初始化代币合约,受益人地址,以及锁仓时间。
  • release():在锁仓期满后,将代币释放给受益人。需要受益人主动调用release()函数提取代币。
    /**
     * @dev 部署时间锁合约,初始化代币合约地址,受益人地址和锁仓时间。
     * @param token_: 被锁仓的ERC20代币合约
     * @param beneficiary_: 受益人地址
     * @param lockTime_: 锁仓时间(秒)
     */
    constructor(
        IERC20 token_,
        address beneficiary_,
        uint256 lockTime_
    ) {
        require(lockTime_ > 0, "TokenLock: lock time should greater than 0");
        token = token_;
        beneficiary = beneficiary_;
        lockTime = lockTime_;
        startTime = block.timestamp;

        emit TokenLockStart(beneficiary_, address(token_), block.timestamp, lockTime_);
    }

    /**
     * @dev 在锁仓时间过后,将代币释放给受益人。
     */
    function release() public {
        require(block.timestamp >= startTime+lockTime, "TokenLock: current time is before release time");

        uint256 amount = token.balanceOf(address(this));
        require(amount > 0, "TokenLock: no tokens to release");

        token.transfer(beneficiary, amount);

        emit Release(msg.sender, address(token), block.timestamp, amount);

三、合约部署实战演示

1. 先发币,给自己铸造10000枚代币。

Remix演示

2. 部署ToeknLocker锁池合约,代币地址为ERC20合约地址,受益人为自己,锁仓期填180秒。

Remix演示

3. 将10000枚代币转入合约。

Remix演示

4. 在锁仓期180秒内调用release()函数,无法取出代币。

Remix演示

5. 在锁仓期后调用release()函数,成功取出代币。

Remix演示

至此,一个简单的锁池合约就完成了。其实锁池和锁币是一个概念,锁池本质上也是锁定LP代币,所以这个合约也能用来进行代币锁仓。如果您要锁池,就填写LP代币的合约地址。如果您要锁币,就填写代币合约地址就可以了。

四、总结

合约的实现本身并不复杂,关键在于,这个合约是否能被用户信任。其实我们用第三方锁池平台的好处就是,用户认可,用户可以查询到,ave等数据平台也支持。如果是自己写合约锁仓的话,用户可能不接受。但是自己写合约,安全啊,安全才是最重要的,不是吗?大家如果有任何相关的技术需求,或者想要交流关于锁池的内容,欢迎找我。V信:btc6540,纸飞机tg:@btc6540


                                                        
声明:该文观点仅代表作者本人,与炒币网无关。炒币网系信息发布平台,仅提供信息存储空间服务。对所包含内容的准确性、可靠性或者完整性不提供任何明示或暗示的保证,并不对文章观点负责。 提示:投资有风险,入市须谨慎。本资讯仅供参阅,不作为投资理财建议。

发表评论

登录后才能评论