# NFT 白名单实现方案 **Published by:** [0xdoux.eth](https://paragraph.com/@0xdoux/) **Published on:** 2022-04-20 **URL:** https://paragraph.com/@0xdoux/nft-2 ## Content 白名单现在已经成为 NFT 项目必备运营方式了,因为 NFT 数量有限,一般就是 1 万个,通过白名单可以刺激社区成员的参与度,比如社群里回答问题、在社交平台上帮助项目方推广、拉新用户等。项目一开始也只会开放给白名单来 mint,然后由这些用户上交易所进行二级市场交易。 本文将介绍下如何在智能合约里实现白名单,除了 NFT 项目,其他需要白名单的项目都可以采用这样的方案。设计思路也很简单,就是使用一个 mapping 来保存用户地址即可,把添加和移除白名单的权限开放给管理员。为什么不使用数组呢,是因为如果是数组实现,那么在验证某个用户是否在白名单里,就需要遍历数组才行,这会增加资源的消耗,即导致 gas 费用比较高。 以下为代码和对应的注释: // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.0 <0.9.0; contract Whitelist { mapping(address => bool) whitelists; address owner; constructor() { owner = msg.sender; // 合约部署后,将管理员自己添加到白名单 whitelists[msg.sender] = true; } modifier onlyOwner() { require(msg.sender == owner, "should be owner"); _; } // 判断 user 是否在白名单里,仅管理员有权限 function isUserInWhitelist(address user) public onlyOwner view returns (bool) { return whitelists[user]; } // 判断自己是否在白名单里 // 前端在调用合约的时候,用来判断自己是不是在白名单里,从而可以控制是否显示 mint 按钮 function amIInWhitelist() public view returns (bool) { return isUserInWhitelist(msg.sender); } // 添加 user 到白名单里,仅管理员有权限 function addToWhitelist(address user) public onlyOwner { whitelists[user] = true; } // 从白名单里移除 user,仅管理员有权限 function removeFromWhitelist(address user) public onlyOwner { whitelists[user] = false; } event AfterMint(address user); // 要求当前用户是否在白名单内 modifier inWhitelist() { require(whitelists[msg.sender], "user not in whitelist"); _; } // 只有在白名单里才能 mint function mint() public inWhitelist { emit AfterMint(msg.sender); } } 通过上述的示例代码就可以实现白名单了,上述代码仅展示了用户是不是在白名单里,但是如果想实现控制用户可以 mint 几张 NFT,则可以使用下述的数据结构: // 在 uint 中保存可以 mint 的数量 mapping(address => uint) whitelists; 在判断是否在白名单里,就只需要可 mint 的数量大于 0 即可,通过可以控制可以 mint 的数量。 ## Publication Information - [0xdoux.eth](https://paragraph.com/@0xdoux/): Publication homepage - [All Posts](https://paragraph.com/@0xdoux/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@0xdoux): Subscribe to updates - [Twitter](https://twitter.com/DouXin): Follow on Twitter