# NFT 白名单实现方案

By [0xdoux.eth](https://paragraph.com/@0xdoux) · 2022-04-20

---

白名单现在已经成为 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 的数量。

---

*Originally published on [0xdoux.eth](https://paragraph.com/@0xdoux/nft-2)*
