erc20代币及水龙头合约

311 阅读2分钟

记录一下今天写的一个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);
    }
}