# 实战案例三:ICO 初始代币销售与空投 **Published by:** [icepy](https://paragraph.com/@icepy/) **Published on:** 2022-03-20 **URL:** https://paragraph.com/@icepy/ico ## Content 最近 APE 空投这么火,是时候说到如何为我们之前做的 UseWeb3NFT 发行代币,在进入编码之前,我们先梳理一下具体的需求: 假设令牌的最大数量为 10000 个 每一个 UseWeb3NFT 持有者可以免费领取 10个 ICO 时每一个令牌的初始价格为 0.0001 eth ERC-20 https://docs.openzeppelin.com/contracts/2.x/api/token/erc20 由于空投部分需要依赖 UseWeb3NFT,所以我们需要写一个接口,使用外部调用的方式获取一些数据 interface IUseWeb3NFT { function balanceOf(address owner) external view returns (uint256 balance); function ownerOf(uint256 tokenId) external view returns (address ownerAddress); } 首先,我们需要去定义价格 uint256 public constant tokenPrice = 0.0001 ether; uint256 public constant tokenMax = 10000 * 10**18; uint256 public constant nftClaimTokenValue = 10 * 10**18; 初始代币销售的价格为 0.0001 eth,代币总数为 10000 个,一个 NFT 可以获取空投的数量为 10 个 接下来我们需要一个 map 去存储已经 Claim 的 tokenId,你总不希望每一个 tokenId 都能重复获取空投吧? mapping (uint256 => bool) claimed; 对于销售部分: function mint(uint256 amount) public payable{ uint256 requireAmount = tokenPrice * amount; require(msg.value >= requireAmount, "sent is incorrect"); uint256 amountAll = amount * 10**18; require((totalSupply() + amountAll) <= tokenMax, "! max"); _mint(msg.sender, amountAll); } 对于空投部分: function claim(uint256[] calldata tokenIds) external{ require(tokenIds.length > 0, "Shortage TokenId"); address sender = msg.sender; uint256 balance = useweb3NFT.balanceOf(sender); require(balance > 0, "Not Balance"); uint256 amount = 0; for (uint i = 0; i < tokenIds.length; i++) { address ownerAddress = useweb3NFT.ownerOf(tokenIds[i]); if (sender == ownerAddress && !claimed[tokenIds[i]]) { amount++; claimed[tokenIds[i]] = true; } } require(amount > 0, "claimed all the tokens"); _mint(sender, amount * nftClaimTokenValue); } 提款方法: function withdraw() public onlyOwner { address _owner = owner(); uint256 amount = address(this).balance; (bool sendStatus, ) = _owner.call{value: amount}(""); require(sendStatus, "Failed send"); } ## Publication Information - [icepy](https://paragraph.com/@icepy/): Publication homepage - [All Posts](https://paragraph.com/@icepy/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@icepy): Subscribe to updates - [Twitter](https://twitter.com/i_icepy): Follow on Twitter