记录一下今天写的一个erc20代币合约以及以及申请该代币的水龙头合约
erc20代币合约: 基础的包括代币信息、铸造销毁,发送等erc20标准
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "./IERC20.sol";
contract DCToken is IERC20 {
// 代币数据
string public name;
string public symbol;
uint8 public decimals = 18;
uint256 public override totalSupply ;
address public owner;
// 余额
mapping(address=>uint256) public override balanceOf;
// 授权额度
mapping(address=>mapping(address=>uint256)) public override allowance;
constructor(string memory _name,string memory _symbol) {
name = _name;
symbol = _symbol;
owner = msg.sender;
}
modifier onlyOwner{
require (msg.sender == owner,"not owner of the erc20");
_;
}
// 直接操作自己代币转账
function transfer(address to,uint256 amount) external override returns(bool){
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender,to,amount);
return true;
}
// 授权操作代币
function approve(address spender,uint256 amount) external override returns(bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender,spender,amount);
return true;
}
function transferFrom(address sender,address recipient,uint256 amount) external override returns(bool){
require(allowance[sender][msg.sender]>=amount,"allowance is not enough");
allowance[sender][msg.sender] -= amount;
balanceOf[sender] -= amount;
balanceOf[recipient] += amount;
emit Transfer(sender,recipient,amount);
return true;
}
function mint(uint256 amount) external onlyOwner {
balanceOf[msg.sender] += amount;
totalSupply += amount;
emit Transfer(address(0),msg.sender,amount);
}
function burn(uint256 amount) external onlyOwner {
balanceOf[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
}
水龙头合约: 1.一个地址只允许2小时内只允许申请一次 2.获取当前水龙头或地址的代币数
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "./IERC20.sol";
contract Faucet {
// 一次申请的代币量
uint256 public constant requestAmount = 10;
// 间隔时间
uint256 public constant intervals = 120 minutes;
// 代币合约地址
address public tokenContract;
// 记录申请的地址
mapping(address => bool) public isRequested;
mapping(address => uint256) public requestTime;
// 接受过代币的地址
event SendToken(address indexed receiver, uint256 indexed amount);
constructor(address _tokenContract) {
tokenContract = _tokenContract;
}
// 给指定地址申请token
function requestDC(address _targetContract) external {
// 先检查上一次申请是否在两小时内
if (
isRequested[msg.sender] &&
block.timestamp - requestTime[msg.sender] > intervals
) {
isRequested[msg.sender] = false;
requestTime[msg.sender] = 0;
}
require(
!isRequested[msg.sender],
"you have requested in last two hours"
);
IERC20 token = IERC20(tokenContract);
// 合约中的token足够
require(
token.balanceOf(address(this)) >= requestAmount,
"not enough token"
);
token.transfer(_targetContract, requestAmount);
isRequested[msg.sender] = true;
requestTime[msg.sender] = block.timestamp;
emit SendToken(_targetContract, requestAmount);
}
// 查询水龙头中剩余DC
function getFaucetToken() external view returns (uint256) {
IERC20 token = IERC20(tokenContract);
return token.balanceOf(address(this));
}
// 获取合约token余额
function getToken(
address _targetContract
) external view returns (uint256 tokenAmount) {
require(
msg.sender == _targetContract,
"you have no permissions to see the balance of token"
);
IERC20 token = IERC20(tokenContract);
return token.balanceOf(_targetContract);
}
}