ERC20 代币水龙头
#
1 需求描述
#
- 实现一个合约,用来发放
ERC20
代币;
- 用户可以调用合约中的
requestForCoin
函数来领取 perAmount
代币,每个 address
只能领取一次;
requestForCoin
函数被调用时,触发 SendToken
事件,以记录领取代币的用户 address
及领取的额度 amount
;
- 合约发放的代币总数为
totalAmount
;
- 代币合约、
perAmount
、totalAmount
均在合约部署时初始化。
2 代码实现
#
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract Faucet {
// 代币合约
IERC20 myCoin;
// 可领取代币总数额
uint256 totalAmount;
// 每次可领取代币数额
uint256 perAmount;
// 领取记录表,领取过的地址记录为true
mapping(address => bool) requestedMap;
/*
* 构造函数,初始化代币合约地址、可领取总数额、每次领取数额
*/
constructor(address _contractAddress, uint256 _totalAmount, uint256 _perAmount) {
myCoin = IERC20(_contractAddress);
totalAmount = _totalAmount;
perAmount = _perAmount;
}
/*
* 领取代币时触发事件
*/
event SendToken(address indexed receiver, uint256 indexed amount);
/*
* 领取代币
*/
function requestForCoin() external returns(bool) {
require(!requestedMap[msg.sender], "You can only request once!");
require(totalAmount >= perAmount, "Faucet Empty!");
myCoin.transfer(msg.sender, perAmount);
totalAmount -= perAmount;
emit SendToken(msg.sender, perAmount);
return true;
}
}