当人渴的时候,就要去水龙头接水;当人想要免费代币的时候,就要去代币水龙头领。代币水龙头就是让用户免费领代币的网站/应用。
实现一个简版的ERC20水龙头,逻辑非常简单:将一些ERC20代币转到水龙头合约里,用户可以通过合约的requestToken()函数来领取100单位的代币,每个地址只能领一次。
uint256 public amountAllowed = 100; // 每次领 100 单位代币
address public tokenContract; // token合约地址
mapping(address => bool) public requestedAddress; // 记录领取过代币的地址
水龙头合约中定义了1个SendToken事件,记录了每次领取代币的地址和数量,在requestTokens()函数被调用时释放。
// SendToken事件
event SendToken(address indexed Receiver, uint256 indexed Amount);
函数 合约中只有两个函数:
- 构造函数:初始化tokenContract状态变量,确定发放的ERC20代币地址。
// 部署时设定ERC20代币合约
constructor(address _tokenContract) {
tokenContract = _tokenContract; // set token contract
}
- requestTokens()函数,用户调用它可以领取ERC20代币。
// 用户领取代币函数
function requestTokens() external {
require(!requestedAddress[msg.sender], "Can't Request Multiple Times!"); // 每个地址只能领一次
IERC20 token = IERC20(tokenContract); // 创建IERC20合约对象
require(token.balanceOf(address(this)) >= amountAllowed, "Faucet Empty!"); // 水龙头空了
token.transfer(msg.sender, amountAllowed); // 发送token
requestedAddress[msg.sender] = true; // 记录领取地址
emit SendToken(msg.sender, amountAllowed); // 释放SendToken事件
}