Using Chainlink VRF in generative art NFT collections is de-facto the standard approach for getting provably random source in smart contracts. By batching the reveal process, instead of making VRF calls for each NFT we can save cost up to 100x (in a collection of 10,000 with batch size of 100).
The reveal process can be automated and further decentralized by having Chainlink Automation call the reveal function when certain criteria is met. In this template there are two configurable criterias: batch size and time interval.
All NFTs in a collection have unique set of traits which determine their value, so it's important they're randomly distributed amongst participants of the drop.
Revealing multiple NFTs with a single random number is achieved by assigning that number as entropy to a range of tokens (batch) and then deriving a new random number for each unique token:
uint256 randomness = uint256(keccak256(abi.encode(entropy, tokenId)));
NFT metadata is the standard description of an asset which allows applications (like wallets and marketplaces) to present them with rich data. You can learn more about this in the Metadata Standards Guide by OpenSea.
In this template we generate an SVG image on-chain and display the random number as text for demonstration purposes. In reality you may want to use it to generate random traits.
Here's an example of how to randomly select the color of an item with the token randomness in Solidity:
string[] memory colors = ["red", "blue", "green", "yellow"];
string memory itemColor = colors[randomness % colors.length];
You can use that color to fill an SVG shape on-chain or generate more complex art off-chain on a metadata server. Take a look at this full example of an on-chain generated SVG art.
Begin by setting the parameters for the NFT collection as environment variables:
Name | Description |
---|---|
NFT_NAME |
Name of the collection. |
NFT_SYMBOL |
Symbol of the collection. Usually a few capital case letters. |
NFT_MAX_SUPPLY |
Maximum amount of tokens that can be minted. |
NFT_MINT_COST |
Cost to mint a single NFT in Ether. |
NFT_REVEAL_BATCH_SIZE |
Minimum number of newly minted tokens required to trigger metadata reveal of a new batch. Set 0 to disable. |
NFT_REVEAL_INTERVAL |
Minimum time required to pass (in seconds) since last metadata reveal to trigger new batch reveal. It's recommended to be combined with batch size param to prevent unefficient batch revealing (ex: the minumum 1 NFT). Set 0 to disable. |
Note: Either batch size or time interval params must be set or metadata won't be revealed. It's also possible for the contract owner to change these params after contract deployment via the setter functions.
Additionally, you need to set variables required for the Hardhat project:
Name | Description |
---|---|
NETWORK_RPC_URL |
Required to deploy to public networks. You can obtain this from websites like Infura, Alchemy or host your own node. |
PRIVATE_KEY |
Deployer's account private key. Can be exported from wallets, i.e. MetaMask. |
ETHERSCAN_API_KEY |
Verify contract code on Etherscan. |
The easiest way to complete this step is by copying the .env.example
file into .env
and replacing the values with your own.
To run the unit tests on the local Hardhat network:
yarn test
To deploy the collection to a network, run:
yarn deploy <network>
The deploy scripts utilize an additional config (helper-hardhat-config.ts
) which contains the parameters required for VRF on test networks like Goerli and Sepolia.
However, you still need to manually replace the subscriptionId
value with your own. To obtain one, you need to Create and fund a VRF subscription.
To have a fully working solution, both Chainlink VRF and Chainlink Automation have to be supported on the network.
To automate the metadata reveal with Chainlink’s Automation network, you need to register new Upkeeep by following this step-by-step guide.
An app is included in this repo which helps you configure and deploy collections from the browser using MetaMask or WalletConnect. It then generates a shareable collection page to mint, monitor when the next reveal is, and browse through the collection of NFTs.
To flatten the contract which is used to open and deploy via Remix IDE:
yarn flatten
- Chainlink Automation Docs
- Chainlink VRF Docs
- Designing Effective NFT Launches
- Smart Batched Auctions
⚠️ Disclaimer: The code used in Chainlink Automation Quickstarts templates comes from Chainlink community members and has not been audited. The Chainlink team disclaims and shall have no liability with respect to any loss, malfunction, or any other result of deploying a Quickstart Template. By electing to deploy a Quickstart Template you hereby acknowledge and agree to the above.