学习测试ICO合约 / 学习智能合约#10

in STEEM CN/中文4 years ago

ico2.jpg

有了前面ERC20代币和智能合约的基础,再来试试ICO合约就会比较轻松地搞定。ICO合约主要是增加了一些复合性和操作的逻辑性,难度上并没有多少增加。

ICO合约的本质就是你给它发以太币,它给你发代币! ERC20代币在前面试过,实现一些标准的函数即可。ICO合约就是在一定的逻辑基础上将这些ERC20代币换成以太币。大家各取所需,皆大欢喜。

ICO合约最主要的是一个互换的函数(卖币),这里需要使用前一篇讲到的接口来调用ERC20代币合约,也就这点稍显复杂。

具体代码如下所示:

pragma solidity >=0.4.22 <0.7.0;


interface token {
    function transfer(address receiver, uint amount) external ;
    //代币合约的接口
}

contract Ico {
    address payable public beneficiary;
    uint public fundingGoal;
    uint public amountRaised;

    uint public deadline;
    uint public price;
    token public tokenReward;

    mapping(address => uint256) public balanceOf;
    bool crowdsaleClosed = false;

    event GoalReached(address recipient, uint totalAmountRaised);
    event FundTransfer(address backer, uint amount, bool isContribution);

    constructor (
        uint fundingGoalInEthers,
        uint durationInMinutes,
        uint etherCostOfEachToken,
        address addressOfTokenUsedAsReward
    ) public {
        beneficiary = msg.sender;
        fundingGoal = fundingGoalInEthers * 1 ether;
        deadline = now + durationInMinutes * 1 minutes;
        price = etherCostOfEachToken * 1 ether;
        tokenReward = token(addressOfTokenUsedAsReward); //代币合约地址,以接口形式实现
    }
    
    receive() external payable {
        //给合约转以太币以换取代币 
        require(!crowdsaleClosed);
        uint amount = msg.value;
        balanceOf[msg.sender] += amount;
        amountRaised += amount;
        tokenReward.transfer(msg.sender, amount / price);
        emit FundTransfer(msg.sender, amount, true);
    }
    
    fallback () external payable { }

    modifier afterDeadline() {
        if (now >= deadline) {
            _;
        }
    }

    function checkGoalReached() public afterDeadline {
        if (amountRaised >= fundingGoal) {
            emit GoalReached(beneficiary, amountRaised);
        }
        crowdsaleClosed = true;
    }


    function safeWithdrawal() public afterDeadline {
        if (amountRaised < fundingGoal) {
            uint amount = balanceOf[msg.sender];
            balanceOf[msg.sender] = 0;
            if (amount > 0) {
                msg.sender.transfer(amount);
                emit FundTransfer(msg.sender, amount, false);
            }
        }

        if (fundingGoal <= amountRaised && beneficiary == msg.sender) {
            beneficiary.transfer(amountRaised);
            emit FundTransfer(beneficiary, amountRaised, false);
        }
    }
    
    function getEthBalance(address addr) public view returns (uint) {
        return addr.balance;
    }
}

新版的Solidity更新了不少的代码规范,我参考网上的文章做了不少改进,有兴趣的朋友不妨也来测试下。

Coin Marketplace

STEEM 0.20
TRX 0.15
JST 0.030
BTC 65037.75
ETH 2638.96
USDT 1.00
SBD 2.81