Using Merkle Trees for NFT Whitelists
merkletree.js
const { MerkleTree } = require("merkletreejs"); const keccak256 = require("keccak256"); let whitelistAddresses = [ "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db", "0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB", "0x617F2E2fD72FD9D5503197092aC168c91465E7f2", "0x17F6AD8Ef982297579C203069C1DbfFE4348c372", "0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678" ] const leafNodes = whitelistAddresses.map(addr => keccak256(addr)); const merkleTree = new MerkleTree(leafNodes, keccak256, { sortPairs: true }); const rootHash = merkleTree.getRoot(); console.log('Whitelist Merkle Tree \n', merkleTree.toString()); console.log("Root Hash: ", rootHash.toString('hex')); console.log("\nwhitelistAddresses count is ", whitelistAddresses.length); console.log("\n--------------------- Merkle Proof for Address -----------------------"); // website create proof const testAddr = "0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678"; //const claimingAddress = leafNodes[0]; //const claimingAddress = keccak256(whitelistAddresses[0]); const claimingAddress = keccak256(testAddr); console.log("claimingAddress is \n", claimingAddress.toString('hex')); const hexProof = merkleTree.getHexProof(claimingAddress); console.log(hexProof); if( hexProof.length > 0){ let paramscon = "[" // to contract params for (p in hexProof) { if(p != hexProof.length - 1) { paramscon += "\"" + hexProof[p] + "\","; }else{ paramscon += "\"" + hexProof[p] + "\"]"; } } console.log(paramscon); }
MerkleVerify.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.4; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; contract MerkleVerify { bytes32 public merkleRoot = 0x4d871defed228a51607c31f9c8419b314f51fa8fbd81b62f958251d9a4e888cd; mapping(address => bool) public whitelistClaimed; function whitelistMint(bytes32[] calldata _merkleProof) public { require(!whitelistClaimed[msg.sender], "Address has already claimed."); bytes32 leaf = keccak256(abi.encodePacked(msg.sender)); require(MerkleProof.verify(_merkleProof, merkleRoot, leaf), "Invalid proof."); whitelistClaimed[msg.sender] = true; } }
https://medium.com/@ItsCuzzo/using-merkle-trees-for-nft-whitelists-523b58ada3f9