I am working on random minting of ERC721 Tokens... I am using Chainlink VRF For randomisation.

The confusion I have is that how can I keep track of NFTs that have been already minted... Because VRF can generate a number(NFT ID) that has already been minted... One option is to use while loop or use an array which will be way too expensive

Any other optimised solution please???

2 Answers 2


something like this is a bit expensive to set up, but minting is cheap, so I think it's along the lines of what you want to do.

Rather than keeping track of what's been minted already, it keeps a set of IDs that haven't been minted and selects from that. The set gets smaller as NFTs are minted.

    pragma solidity ^0.8.7

    import "hardhat/console.sol";

    contract RandomMints {

    uint[] notMinted;

    function createSet() external {
        // this is a bit expensive but a one off
        // txn gas 2282618 in remix
        for(uint i; i < 100; ++i){

    function pickId() external returns (uint) {
        // txn gas 37430 in remix
        uint numLeft = notMinted.length;
        console.log("num of NFTs not minted:", numLeft);

        // pick a number between 0 - num of unminted NFTs -1
        uint rand = block.timestamp % (numLeft - 1);  //not really random
        uint idSelected = notMinted[rand];

        // now reduce the set. it doesn't matter if we mix up the order as it adds more entropy
        // get rid of the picked id by overwriting it with the last id/element
        notMinted[rand] = notMinted[numLeft -1];
        // pop the last (now duplicated) id/element off the array

        console.log("id selected:", idSelected);
        return idSelected;
  • I am using the same logic and its working fine. but my question is that when 90/100 NFTs have been minted randomly, then according to the following code: while(flag==true) { tokenId = random() % 100; flag = IsMinted[tokenId]; if(flag == false) break; } The contract can make a lot of tries using this while loop.. hence the call will be very expensive in terms of gas...I am looking for an optimised solution. Aug 30, 2022 at 9:29
  • sorry, I misunderstood. I've changed the answer. hope it helps
    – sola24
    Aug 30, 2022 at 10:07
  • Great! Thank You so much for the answer! Aug 30, 2022 at 12:09

What about to have a mapping(uint => bool) to know which ID number was already minted?

For example

mapping(uint => bool) minted;

function mint(uint id) {
  require(!minted[id],"already minted")
  //mint the NFT

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.