I've been revisiting ethers.js
recently to refresh my understanding of the details and to write a simple tutorial called "WTF Ethers" for beginners.
Twitter: @0xAA_Science
Community: Website wtf.academy | WTF Solidity | discord | WeChat Group Application
All the code and tutorials are open-sourced on GitHub: github.com/WTFAcademy/WTF-Ethers
In this lesson, we will write a script that utilizes the Merkle Tree to whitelist addresses for minting NFTs. If you are not familiar with the Merkle Tree contract, please refer to WTF Solidity 36: Merkle Tree.
Merkle Tree
A Merkle Tree, also known as a hash tree, is a fundamental cryptographic technology used in blockchain systems, including Bitcoin and Ethereum. A Merkle Tree is a bottom-up constructed binary tree, where each leaf node represents the hash of some data, and each non-leaf node represents the hash of its two child nodes.

The Merkle Tree allows for efficient and secure verification of large data structures (Merkle Proof). For a Merkle Tree with N
leaf nodes, given the known root value, verifying whether a specific data is valid (belonging to a leaf node of the Merkle Tree) only requires log(N)
data (also known as a proof), which is highly efficient. If the data is incorrect or the provided proof is wrong, it is not possible to obtain the root value. In the example below, the Merkle proof for leaf L1 includes "Hash 0-1"
and "Hash 1"
: knowing these two values allows us to verify if the value of L1
is present in the Merkle Tree's leaf nodes.

Merkle Tree Contract Overview
In WTF Solidity 36: Merkle Tree, the MerkleTree
contract is used to validate whitelisted addresses for minting NFTs. Let's briefly explain the two functions used here:
-
Constructor: Initializes the name, code, and root of merkle tree of the NFT contract.
-
mint()
: Uses the Merkle Proof to validate the whitelisted address and mint the NFT. The function parameters are the whitelisted addressaccount
, thetokenId
to be minted, and theproof
.
MerkleTree.js
MerkleTree.js
is a JavaScript package for building Merkle Trees and generating Merkle Proofs (Github link). You can install it via npm:
Here, we demonstrate how to generate a Merkle Tree with leaf nodes containing 4 whitelisted addresses.
-
Create an array of whitelisted addresses.
-
Hash the data using
keccak256
(matching the hashing function used in Solidity) to create the leaf nodes. -
Create the Merkle Tree, using
keccak256
as the hashing function. The optional parametersortPairs: true
keeps the same processing logic as the Merkle Tree contract. -
Get the
root
of the Merkle Tree. -
Get the
proof
for the leaf node at index0
.
Whitelist Address Token Minting with Merkle Tree
Here, we provide an example of how to validate a whitelist and mint NFTs using MerkleTree.js
and ethers.js
.
-
Generate the Merkle Tree.
-
Create provider and wallet.
const provider = new ethers.JsonRpcProvider(ALCHEMY_GOERLI_URL); // Create wallet object using private key and provider const privateKey = '0x227dbb8586117d55284e26620bc76534dfbd2394be34cf4a09cb775d593b6f2b' const wallet = new ethers.Wallet(privateKey, provider) ```
-
Create contract factory to prepare for deploying the contract.
-
Deploy the NFT contract using the contract factory
-
Call the
mint()
function to validate the whitelist using the merkle tree and mint an NFT for the first address. After successful minting, the NFT balance will be 1.
For Production
To use the Merkle Tree to validate whitelist and issue NFTs in production, follow these steps:
- Determine the whitelist.
- Generate the Merkle Tree for the whitelist on the backend.
- Deploy the NFT contract and save the root of the Merkle Tree in the contract.
- When a user wants to mint, request the
proof
corresponding to the address from the backend. - The user can then call the
mint()
function to mint the NFT.
Summary
In this lesson, we introduced the Merkle Tree and used MerkleTree.js
and ethers.js
to create, validate whitelist, and mint NFTs.