以太坊实现NFT白名单合约,并且实现前端传入对应的白名单地址来创建(mint)NFT

文章介绍了如何使用Solidity实现一个基于ERC721标准的NFT合集智能合约,该合约结合默克尔树进行白名单管理。通过MerkleProof库验证地址,并在前端利用merkletreejs进行白名单验证和mint操作。合约使用OpenZeppelin库,确保安全性和标准性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍

一个开源solidity合集仓库
https://github.com/qdwds/smart-contracts
以太坊ERC721全栈开发开NFT合集从入门到项目实战项目
https://learnblockchain.cn/course/31
https://edu.51cto.com/course/33566.html

一起学习吧

我们一起沟通、交流、学习吧!

白名单NFT

默克尔树

Markle Tree 也叫做默克尔树或者哈希树,是区块链的底层加密技术。Markle Tree是一颗倒立的树,根部在最上面,叶子在下面,每片叶子就对应数据的哈希,而且每个叶子的两个节点也是哈希。

默克尔树的原理是将大量数据分割成小块,然后逐层进行哈希运算,最终生成一个根哈希值。具体过程如下:

  • 将要传输的数据分割成固定大小的块,每个块的大小可以根据实际需求确定。
  • 对每个块进行哈希运算,得到一个哈希值
  • 将相邻的两个哈希值进行合并,形成一个新的哈希值。
  • 重复步骤3,直到最后只剩下一个哈希值,这个哈希值就是默克尔树的根哈希值。

在这里插入图片描述

智能合约默克尔树白名单

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract MerkleTree is ERC721 {
    using Counters for Counters.Counter;
    bytes32 public immutable root; // Merkle树的根
    mapping(address => bool) public whiteLists; // 记录已经mint的地址
    Counters.Counter private _tokenIdCounter;

    // 构造函数,初始化NFT合集的名称、代号、Merkle树的根
    constructor(bytes32 merkleroot) ERC721("nft", "nft") {
        root = merkleroot;
    }

    // 利用Merkle树验证地址并完成mint
    function mint(
        address account,
        bytes32[] calldata proof
    ) external {
        require(_verify(_leaf(account), proof), "Invalid merkle proof"); // Merkle检验通过
        require(!whiteLists[account], "Already minted!"); // 地址没有mint过
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _mint(account, tokenId); // mint
        whiteLists[account] = true; // 记录mint过的地址
    }

    // 计算Merkle树叶子的哈希值
    function _leaf(address account) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(account));
    }

    // Merkle树验证,调用MerkleProof库的verify()函数
    function _verify(bytes32 leaf, bytes32[] memory proof)
        internal
        view
        returns (bool)
    {
        return MerkleProof.verify(proof, root, leaf);
    }
}

前端实现默克尔树白名单mint

使用到merkletreejs来验证白名单列表

import { keccak256 } from "ethers/lib/utils";
import { ethers } from "hardhat"
import { MerkleTree } from "merkletreejs";
const white = [
    "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
    "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
    "0x90F79bf6EB2c4f870365E785982E1f101E93b906"
]
const main = async ()=> {
    // 生成MerkleTree
    const leaf = white.map(x => keccak256(x));
    const markletree = new MerkleTree(leaf, keccak256, {sortPairs: true});
    const root = markletree.getHexRoot();
   
    // 部署合约
    const MarkleTree = await ethers.getContractFactory("MarkleTree");
    const tree = await MarkleTree.deploy(root);
    console.log(tree.address);
    await tree.deployed();

    // 白名单 mint
    for (let i = 0; i < white.length; i++) {
        const proof = markletree.getHexProof(leaf[i]);
        await tree.mint(white[i], proof);
        console.log(await tree.whiteLists(white[i]));
    }

    //  不存在的白名单 会报错
    const proof = markletree.getHexProof(leaf[0]);
    await tree.mint("0x71bE63f3384f5fb98995898A86B02Fb2426c5788", proof);
}

main()
    .catch(err =>{
        console.log(err);
        process.exit(1);
    })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值