{"author":{"address":null,"user":"https://learnblockchain.cn/people/18158"},"content":{"body":"# 前言\r\n\u003e 本文主要实现代币锁合约的开发、测试、部署全流程，以及对该合约使用场景分析介绍；\r\n# 代币锁\r\n**定义**：将一定数量的代币在一段时间内限制其交易和转移的行为，主要目标是激励长期承诺，阻止早期投资者或团队成员迅速出售代币获利，然后退出项目。\r\n#### 功能\r\n1.  **时间锁定**：代币在特定的时间段内无法转移或使用。这是最常见的锁仓方式，用于限制代币的流通，以防止投资者过早地出售或交易代币，从而维护代币的稳定性和价值。\r\n2.  **数量锁定**：将一定数量的代币存储在一个地址中，要求在一定的时间段内保持该数量的锁定状态。这种锁仓机制可以用于项目的众筹阶段或私募轮等，确保项目团队或投资者在一段时间内持有一定数量的代币，以体现其对项目的承诺和信心。\r\n3.  **条件锁定**：根据特定的条件来触发或解除锁仓状态。这种锁仓机制通常用于智能合约中，通过设定一些条件，如特定日期、价格或事件等，来限制或释放数字资产的流通。条件锁定可以用于项目的预售期、团队解锁、投资者奖励等，以实现更灵活的资产管理和治理。\r\n#### 解锁的方式\r\n1.  **线性解锁**：代币逐渐按时间线性解锁，比如每月解锁一定比例。\r\n2.  **阶段性解锁**：代币在特定时间点或达到特定里程碑时解锁。\r\n3.  **一次性解锁**：所有锁定的代币在特定时间点一次性全部解锁。\r\n\r\n#### 场景\r\n1.  **团队和顾问**：项目开发人员和顾问可能会使他们的代币受到锁定，以确保持续的承诺。\r\n2.  **投资者**：ICO或代币销售的早期投资者可能也会经历锁定期，以避免短期投机。\r\n3.  **创始人**：项目创始人或核心团队成员可能会使他们的代币受到锁定，以使其利益与项目的长期成功相一致。\r\n4.  **流动性提供者**：代币锁一般是用来锁仓流动性提供者（LP）代币的，以确保流动性在一段时间内不会被撤走。\r\n#### 优点\r\n1.  **透明度**：智能合约确保对锁定要求的透明和自动执行。\r\n2.  **灵活性**：项目可以定制锁定系统以满足其独特需求，促进问责制。\r\n3.  **安全性**：利用区块链技术使该过程更加安全，不受中央操纵的影响。\r\n4.  **长期发展**：代币锁定通过减少投机活动和建立投资者信心，促进了项目的长期发展。\r\n\r\n# 合约开发\r\n**合约说明**：主要实现锁定代币和释放代币功能\r\n```\r\n// SPDX-License-Identifier: MIT\r\n// wtf.academy\r\npragma solidity ^0.8.22;\r\n\r\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\r\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\r\nimport \"hardhat/console.sol\";\r\n\r\n/**\r\n * @dev ERC20代币时间锁合约。受益人在锁仓一段时间后才能取出代币。\r\n */\r\ncontract TokenLocker {\r\n\r\n    // 事件\r\n    event TokenLockStart(address indexed beneficiary, address indexed token, uint256 startTime, uint256 lockTime);\r\n    event Release(address indexed beneficiary, address indexed token, uint256 releaseTime, uint256 amount);\r\n\r\n    // 被锁仓的ERC20代币合约\r\n    IERC20 public immutable token;\r\n    // 受益人地址\r\n    address public immutable beneficiary;\r\n    // 锁仓时间(秒)\r\n    uint256 public immutable lockTime;\r\n    // 锁仓起始时间戳(秒)\r\n    uint256 public immutable startTime;\r\n\r\n    /**\r\n     * @dev 部署时间锁合约，初始化代币合约地址，受益人地址和锁仓时间。\r\n     * @param token_: 被锁仓的ERC20代币合约\r\n     * @param beneficiary_: 受益人地址\r\n     * @param lockTime_: 锁仓时间(秒)\r\n     */\r\n    constructor(\r\n        IERC20 token_,\r\n        address beneficiary_,\r\n        uint256 lockTime_\r\n    ) {\r\n        require(lockTime_ \u003e 0, \"TokenLock: lock time should greater than 0\");\r\n        token = token_;\r\n        beneficiary = beneficiary_;\r\n        lockTime = lockTime_;\r\n        startTime = block.timestamp;\r\n\r\n        emit TokenLockStart(beneficiary_, address(token_), block.timestamp, lockTime_);\r\n    }\r\n\r\n    /**\r\n     * @dev 在锁仓时间过后，将代币释放给受益人。\r\n     */\r\n    function release() public {\r\n        require(block.timestamp \u003e= startTime+lockTime, \"TokenLock: current time is before release time\");\r\n\r\n        uint256 amount = token.balanceOf(address(this));\r\n        require(amount \u003e 0, \"TokenLock: no tokens to release\");\r\n\r\n        token.transfer(beneficiary, amount);\r\n\r\n        emit Release(msg.sender, address(token), block.timestamp, amount);\r\n    }\r\n}\r\n# 编译指令\r\n# npx hardhat compile\r\n```\r\n# 合约测试\r\n**测试说明**：测试采用获取当前代币时间戳来，从而实现对时间到期的模拟\r\n```\r\nconst {ethers,getNamedAccounts,deployments} = require(\"hardhat\");\r\nconst { assert,expect } = require(\"chai\");\r\ndescribe(\"代币锁\",function(){\r\n    let token;\r\n    let TokenLocker;\r\n    let addr1;\r\n    let addr2;\r\n    let firstAccount;\r\n    let secondAccount;\r\n    beforeEach(async function(){\r\n        await deployments.fixture([\"token\",\"TokenLocker\"]);\r\n        [addr1,addr2]=await ethers.getSigners();\r\n        firstAccount=(await getNamedAccounts()).firstAccount;\r\n        secondAccount=(await getNamedAccounts()).secondAccount;\r\n        //代币合约\r\n        const tokenDeployment = await deployments.get(\"MyToken\");\r\n        token = await ethers.getContractAt(\"MyToken\",tokenDeployment.address);//已经部署的合约交互\r\n        //代币锁合约\r\n        const TokenLockerDeployment = await deployments.get(\"TokenLocker\");\r\n        TokenLocker = await ethers.getContractAt(\"TokenLocker\",TokenLockerDeployment.address);//已经部署的合约交互\r\n    });\r\n    describe(\"代币锁合约\",function(){\r\n        it(\"代币锁合约测试\",async function(){\r\n        //    console.log(await TokenLocker.release()) \r\n        //转入代币合约\r\n            await token.transfer(TokenLocker.address,ethers.utils.parseEther(\"20\"));\r\n            let balanceOf=await token.balanceOf(TokenLocker.address)\r\n            console.log(\"合约中的代币金额\",`${ethers.utils.formatEther(balanceOf)} ETH`)\r\n           //获取当前时间\r\n           const currentTime = await ethers.provider.getBlock(\"latest\").then(block =\u003e block.timestamp);\r\n           console.log(currentTime)\r\n            // 模拟时间流逝，增加 时间（200 秒）\r\n            await ethers.provider.send(\"evm_increaseTime\", [200]);\r\n            await ethers.provider.send(\"evm_mine\", []); // 挖一个区块，使时间生效\r\n            console.log(await ethers.provider.getBlock(\"latest\").then(block =\u003e block.timestamp))\r\n            //时间到释放代币\r\n            await TokenLocker.release();//\r\n\r\n            console.log(\"释放后的合约里的代币\",`${ethers.utils.formatEther(await token.balanceOf(TokenLocker.address))} ETH`)\r\n            \r\n        })\r\n    })\r\n})\r\n# 测试指令\r\n# npx hardhat test ./test/xxx.js\r\n```\r\n# 合约部署\r\n```\r\nmodule.exports = async function ({getNamedAccounts,deployments}) {\r\n  const  firstAccount= (await getNamedAccounts()).firstAccount;\r\n  const  secondAccount= (await getNamedAccounts()).secondAccount;\r\n  const {deploy,log}=deployments;\r\n  //获取token合约地址\r\n  const MyToken=await deployments.get(\"MyToken\");\r\n  const TokenAddress = MyToken.address;\r\n  console.log(TokenAddress)\r\n  const TokenLocker=await deploy(\"TokenLocker\",{\r\n    from:firstAccount,\r\n    args: [TokenAddress,firstAccount,180],//参数 参数  被锁仓的ERC20代币合约、受益人地址、锁仓时间\r\n    log: true,\r\n  })\r\n  console.log('TokenLocker合约地址',TokenLocker.address)\r\n\r\n  }\r\n  module.exports.tags = [\"all\", \"TokenLocker\"];\r\n# 部署指令\r\n# npx hardhat deploy\r\n```\r\n# 总结\r\n以上就是代币锁合约开发、测试、部署全流程，以及对代币锁的使用场景的分析。`注意`:测试中主要通过获取当前区块时间戳的方式，从而实现过期时间的模拟测试；","title":"关于代币锁合约的使用场景介绍和实现"},"history":null,"timestamp":1740899400,"version":1}