账户
0xe9...d6e5
0xe9...D6E5

0xe9...D6E5

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.0+commit.c7dfd78e
语言
Solidity
合同源代码
文件 1 的 1:TokenPresale.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IERC20 {
    function transfer(address recipient, uint256 amount)
        external
        returns (bool);

    function balanceOf(address account) external view returns (uint256);
}

contract TokenPresale {
    IERC20 public token;
    address public owner;
    address public pendingOwner;
    uint256 public price;
    bool public saleActive;
    bool private locked;

    event Purchase(address indexed buyer, uint256 amount);
    event PriceUpdated(uint256 newPrice);
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    constructor(address _token, uint256 _price) {
        require(_price > 0, "Price should be greater than 0");

        token = IERC20(_token);
        owner = msg.sender;
        price = _price;
        saleActive = false;
        locked = false;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this function");
        _;
    }

    modifier onlyPendingOwner() {
        require(
            msg.sender == pendingOwner,
            "Only pending owner can call this function"
        );
        _;
    }

    modifier noReentrancy() {
        require(!locked, "No reentrancy allowed");
        locked = true;
        _;
        locked = false;
    }

    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "New owner is the zero address");
        pendingOwner = newOwner;
    }

    function acceptOwnership() external onlyPendingOwner {
        emit OwnershipTransferred(owner, pendingOwner);
        owner = pendingOwner;
        pendingOwner = address(0);
    }

    function startSale() external onlyOwner {
        require(!saleActive, "Sale already active");
        saleActive = true;
    }

    function stopSale() external onlyOwner {
        require(saleActive, "Sale not active");
        saleActive = false;
    }

    function buyTokens(uint256 tokenAmount) external payable noReentrancy {
        require(saleActive, "Sale not active");
        require(tokenAmount > 0, "Cannot purchase 0 tokens");

        uint256 tokenToTransfer = tokenAmount * 10**18;
        require(
            token.balanceOf(address(this)) >= tokenToTransfer,
            "Insufficient tokens"
        );

        uint256 requiredETH = tokenAmount * price;
        require(msg.value >= requiredETH, "Insufficient ETH sent");

        token.transfer(msg.sender, tokenToTransfer);
        emit Purchase(msg.sender, tokenAmount);

        if (msg.value > requiredETH) {
            payable(msg.sender).transfer(msg.value - requiredETH);
        }
    }

    function setPrice(uint256 _price) external onlyOwner {
        require(_price > 0, "Price should be greater than 0");
        price = _price;
        emit PriceUpdated(_price);
    }

    function withdrawETH() external onlyOwner {
        require(!saleActive, "Sale must be stopped before withdrawing ETH");
        payable(owner).transfer(address(this).balance);
    }

    function withdrawTokens() external onlyOwner {
        require(!saleActive, "Sale must be stopped before withdrawing tokens");
        token.transfer(owner, token.balanceOf(address(this)));
    }
}
设置
{
  "compilationTarget": {
    "TokenPresale.sol": "TokenPresale"
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"PriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Purchase","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"buyTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"saleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]