【dApp实战】- whitelist

611 阅读3分钟

写在前面

入门Web3的一个比较有基础、比较全面的dApp项目-白名单

具体的文档在这里,大家自行跳转查看即可。WhiteList

这是我的B站视频地址,建议搭配视频一起食用视频地址

合约部分

我们现在想想,一个whitelist需要做的事情是什么?或者说他有哪些特点

  1. whitelist可以看作一个篮子
  2. 容量肯定是有限的并且在生成的时候就得固定好
  3. 暴露方法让所有人能够添加到篮子中
  4. ...

上述就是目前我们能够想到的特点 接下来我们再将这些特点用Solidity语言实现

  1. 篮子可以用数组实现
  2. 容量可以在合约部署的时候设置好
  3. 添加到篮子中的方法可以用函数实现
  4. 篮子中存的应该是钱包的地址,也就是address类型

第一个版本的合约

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;


contract Whitelist {

    // 白名单的最大容量
    uint8 public maxWhitelistedAddresses;

    // 白名单篮子
    address[] public whitelistedAddresses;

    // 当前白名单篮子中的地址个数
    uint8 public numAddressesWhitelisted;

    // 构造函数,设置白名单最大的容量
    constructor(uint8 _maxWhitelistedAddresses) {
        maxWhitelistedAddresses =  _maxWhitelistedAddresses;
    }

    // 向外暴露方法,允许所有人能够将自己的钱包地址添加到白名单中
    function addAddressToWhitelist() public {
        require(maxWhitelistedAddresses > numAddressesWhitelisted, "More addresses cant be added, limit reached");
        // 处理白名单为空的情况
        if (numAddressesWhitelisted == 0){
            whitelistedAddresses.push(msg.sender);
            numAddressesWhitelisted++;
        }
        bool flag = true;
        for(uint8 i = 0; i < numAddressesWhitelisted; i++){
            if (msg.sender == whitelistedAddresses[i]){
                flag = false;
                break;
            }
        }
        if (flag) {
            whitelistedAddresses.push(msg.sender);
            numAddressesWhitelisted++;
        }
    }
}

这一个版本的合约其实已经实现了咱们的需求了,但是有点不太好理解,主要是在添加白名单这一块,用数组来存白名单不太好,数组的数据结构对于这种场景不太好操作。接下来我们来分享另一种方式,也就是文档提供的方案。

第二个版本的合约

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

contract Whitelist {
    // Max number of whitelisted addresses allowed
    uint8 public maxWhitelistedAddresses;

    // Create a mapping of whitelistedAddresses
    // if an address is whitelisted, we would set it to true, it is false by default for all other addresses.
    mapping(address => bool) public whitelistedAddresses;


    // numAddressesWhitelisted would be used to keep track of how many addresses have been whitelisted
    // NOTE: Don't change this variable name, as it will be part of verification
    uint8 public numAddressesWhitelisted;

    // Setting the Max number of whitelisted addresses
    // User will put the value at the time of deployment
    constructor(uint8 _maxWhitelistedAddresses) {
        maxWhitelistedAddresses =  _maxWhitelistedAddresses;
    }

    /**
        addAddressToWhitelist - This function adds the address of the sender to the
        whitelist
     */
    function addAddressToWhitelist() public {
        // check if the user has already been whitelisted
        require(!whitelistedAddresses[msg.sender], "Sender has already been whitelisted");
        // check if the numAddressesWhitelisted < maxWhitelistedAddresses, if not then throw an error.
        require(numAddressesWhitelisted < maxWhitelistedAddresses, "More addresses cant be added, limit reached");
        // Add the address which called the function to the whitelistedAddress array
        whitelistedAddresses[msg.sender] = true;
        // Increase the number of whitelisted addresses
        numAddressesWhitelisted += 1;
    }


}

这个版本我是从文章中直接摘下来的,英文注释大家看不懂没关系,大体逻辑和咱们第一个版本的合约大差不差。

这个版本呢就非常好了,对于存储白名单的数据结构非常好用,并且理解成本大大降低。当然这个合约也不是没有任何缺点。就是Gas有点高,在合约中建议不使用require语句,他的gas比error贵点

具体在合约中哪种异常处理更便宜,大家看这个文档就好WTF

然后编译、部署等等操作就不聊了,大家自行看官网文章步骤就行....

前端部分

前端部分个人感觉没有什么难度,个人觉得需要注意以下几点

  1. 了解Web3Modal的使用流程。我这里说的使用流程不是说官网提供的Example,而是这个项目中的使用流程。大家应该知道,我们目前作为初学者,缺的就是项目经验,当市面上出现一个非常好、非常优秀、非常干净、非常优雅的项目源码时,我们需要做的尽量模仿这些项目的执行流程,模块的布局、项目的分层等等。看的项目多了,模仿的项目多了,最终沉淀成自己的代码风格。
  2. 每个函数的执行逻辑。这个就涉及到具体的源码部分了。上面这个可以理解成是一种编程思想,而这个点就是源码解读。这里的话就需要根据实际的需求对项目的执行逻辑、执行流程进行疏通。