Skip to content

Instantly share code, notes, and snippets.

@umarrazay
Last active June 12, 2023 10:06
Show Gist options
  • Save umarrazay/bbd77878d190295319dcf7c9e04bc1e2 to your computer and use it in GitHub Desktop.
Save umarrazay/bbd77878d190295319dcf7c9e04bc1e2 to your computer and use it in GitHub Desktop.
Whitelisting with Merkle Tree in Smart Contract

Step1=>First run the MerkleTree.js file it will provide you the input as shown in the image1 Now you have Merkle Root Hash and Merkle Proof Not Go to the remix and pass the merkle root hash in the field as show in image2 Now deploy the contract and go to the safeMint function and pass the merkle proof that we have generated earlier in step 1 Make sure you are calling the mint function from the same address , for which you have genreate the merkle proof. so it will mint the NFT on your address. and mapping in the contract is set to true to make sure that you have mint/claim the NFT.

explaination of MerkleTree.js File print the merkle root see line 17 and 18 , we are appending 0x with this At line number 21 we are passing first address to keccak256 algo to genrate hash and the in line 22 we are getting proof of this hashed address with the help of tree.getHeProof function.

image1 image2 image3

Note: For every address merkle proof will be different you have to genrate the merkle proof separately for each address if you have any question you can ask in comment section.

const { MerkleTree } = require('merkletreejs');
const keccak256 = require('keccak256');
// these addresess are from remix
let whitelistedAddresses = [
"0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2",
"0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db",
"0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB",
"0x617F2E2fD72FD9D5503197092aC168c91465E7f2"
]
const leaves = whitelistedAddresses.map(addr => keccak256(addr));
const tree = new MerkleTree(leaves, keccak256, { sortPairs: true });
const rootHash = '0x'+tree.getRoot().toString('hex');
console.log(`Merkle Root for this three is ${rootHash}`); // print merkle root that we need to pass when deploying the contract
const leaf = "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4"; // here you will change the address for which you want to genrate the merkle proof
const HashedLeaf = keccak256(leaf);
const proof = tree.getHexProof(HashedLeaf);
console.log(`Merkle proof for this address ${leaf} is `);
console.log(JSON.stringify(proof)); // converting our proof to stringify array
// passing these three paramertes to tree.verify function to check weather the address is belong to the tree or not.
// it will print true if the address belongs to the tree and false if inot
console.log(tree.verify(proof,HashedLeaf,rootHash) );
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
contract whitelist is ERC721 {
bytes32 public merkleTreeRootHash;
uint256 public tokenid = 1;
constructor(bytes32 _merkleTreeRootHash) ERC721("WhiteListed NFT", "WNFT") {
merkleTreeRootHash = _merkleTreeRootHash;
}
mapping(address => bool) public isWhitelistedAddressClaimed;
function safeMint(bytes32[] calldata _merkleProof) public {
require(!isWhitelistedAddressClaimed[msg.sender], "Address has already minted a whitelisted NFT.");
bytes32 leafToVerify = keccak256(abi.encodePacked(msg.sender));
require(
MerkleProof.verify(_merkleProof, merkleTreeRootHash, leafToVerify),
"Invalid address to mint the NFT."
);
_safeMint(msg.sender, tokenid);
tokenid++;
isWhitelistedAddressClaimed[msg.sender] = true;
}
address public deployer = msg.sender;
uint256 public balance = balanceOf(deployer);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment