写在前面
入门Web3的一个比较有基础、比较全面的dApp项目-白名单
具体的文档在这里,大家自行跳转查看即可。WhiteList
这是我的B站视频地址,建议搭配视频一起食用视频地址
合约部分
我们现在想想,一个whitelist需要做的事情是什么?或者说他有哪些特点
- whitelist可以看作一个篮子
- 容量肯定是有限的并且在生成的时候就得固定好
- 暴露方法让所有人能够添加到篮子中
- ...
上述就是目前我们能够想到的特点 接下来我们再将这些特点用Solidity语言实现
- 篮子可以用数组实现
- 容量可以在合约部署的时候设置好
- 添加到篮子中的方法可以用函数实现
- 篮子中存的应该是钱包的地址,也就是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
然后编译、部署等等操作就不聊了,大家自行看官网文章步骤就行....
前端部分
前端部分个人感觉没有什么难度,个人觉得需要注意以下几点
- 了解Web3Modal的使用流程。我这里说的使用流程不是说官网提供的Example,而是这个项目中的使用流程。大家应该知道,我们目前作为初学者,缺的就是项目经验,当市面上出现一个非常好、非常优秀、非常干净、非常优雅的项目源码时,我们需要做的尽量模仿这些项目的执行流程,模块的布局、项目的分层等等。看的项目多了,模仿的项目多了,最终沉淀成自己的代码风格。
- 每个函数的执行逻辑。这个就涉及到具体的源码部分了。上面这个可以理解成是一种编程思想,而这个点就是源码解读。这里的话就需要根据实际的需求对项目的执行逻辑、执行流程进行疏通。