有了前面ERC20代币和智能合约的基础,再来试试ICO合约就会比较轻松地搞定。ICO合约主要是增加了一些复合性和操作的逻辑性,难度上并没有多少增加。
ICO合约的本质就是你给它发以太币,它给你发代币! ERC20代币在前面试过,实现一些标准的函数即可。ICO合约就是在一定的逻辑基础上将这些ERC20代币换成以太币。大家各取所需,皆大欢喜。
ICO合约最主要的是一个互换的函数(卖币),这里需要使用前一篇讲到的接口来调用ERC20代币合约,也就这点稍显复杂。
具体代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| 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更新了不少的代码规范,我参考网上的文章做了不少改进,有兴趣的朋友不妨也来测试下。
This page is synchronized from the post: ‘学习测试ICO合约 / 学习智能合约#10’