How to Create an Off-Chain NFT Allowlist
Learn how to create off-chain allowlists for NFT PFP Projects
In a previous article, we explored the problems that allowlists solve (namely, generating and streamlining demand in your project) and implemented an on-chain version.
Mekaverse, one of the most popular NFT projects in 2021, used off-chain allowlists to streamline demand
Although secure and fully functional, the on-chain solution comes with its caveats. In an on-chain implementation, the project owner (or contract) must upload and store all allowlisted addresses on the blockchain. If your project operates on a platform like Ethereum, this could mean a fortune in gas fees.
Fortunately, you can bypass these fees without compromising on security. This article will explore how to implement and store an allowlist off-chain using digital signatures and OpenZeppelin’s ECDSA library.
Creating the Off-Chain Allowlist
Step 1: Install Node and npm
In case you haven’t already, install node and npm on your local machine.
Ensure that node is at least v14 or higher by entering the following command in your terminal:
Step 2: Create a Hardhat project
We’re going to set up our project using Hardhat, the industry-standard development environment for Ethereum smart contracts. Additionally, we’ll also install OpenZeppelin contracts.
To set up Hardhat, run the following commands in your terminal:
Choose Create a Javascript project
from the menu and accept all defaults. To ensure everything is installed correctly, run the following command in your terminal:
To install OpenZeppelin:
Step 3: Write the smart contract
Now, let’s write a basic NFT smart contract that can operate with an off-chain allowlist. To do this, we need two things:
- A Solidity mapping
signatureUsed
to check if a particular signature has been used before. - A function
recoverSigner
that returns the public address of the wallet used to create a particular signature (or signed message).
Open the project in your favorite code editor (e.g., VS Code), and create a new file called NFTAllowlist.sol
in the contracts
folder. Add the following code to this file:
Notice that the preSale
and recoverSigner
functions take in a hash
and a signature
as arguments. The former is the hashed version of any message that we want to sign, and the latter is the hashed message signed using a wallet’s private key. We will generate both these values in the next step.
Compile the contract and make sure everything is working by running:
Step 4: Create the Off-Chain Allowlist
Let’s now write a script that allows us to implement an allowlist off-chain. To do this, create a new file called run.js
in the scripts folder, then add the following code:
Run the script using the following command:
You should see output that looks something like this:
Notice that we did not store allowlisted wallets on-chain. Instead, we stored them locally and performed the following steps:
- Check if the selected wallet is allowlisted.
- If allowlisted, sign the hashed version of the wallet’s public address using a secret private key.
- Pass the hashed address and the signature to the minting function of the smart contract.
- In the minting function, recover the signer and check if the signer is the owner of the smart contract. If yes, allow mint. Otherwise, return an error.
Conclusion
Congratulations! You now know how to implement an off-chain NFT allowlist.
If you enjoyed this tutorial about creating on-chain allowlists, tweet us at [@Alchemy] and give us a shoutout!
Don’t forget to join our Discord server to meet other blockchain devs, builders, and entrepreneurs!
Ready to start building your NFT collection?
Create a free Alchemy account and do share your project with us!