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