Solidity – How to Guarantee Unique Number Combinations Based on Chainlink VRFv2

chainlinksolidity

I want to mint NFTs based on random numbers retrieved from Chainlink VRFv2.
And what I want to achieve is to make sure that each of the generated NFT is unique.\

For example, when I send request to Chainlink for lets say three random numbers, I'm retrieving uint256[] randomNumbers array like this:

[
  532267..3463,
  234645..3742,
  747424..1134
];

Then based on that numbers I wanna make sure that I get the random number within certain range, lets say between 1 and 10, so I do something like this:

uint256[3] memory myRandomNumbers = [
    (randomNumbers[0] % 10) + 1,
    (randomNumbers[1] % 10) + 1,
    (randomNumbers[2] % 10) + 1
];

So I'm receiving array with my numbers like:

[ 3, 7, 8];

Which is 3-7-8 combination. And what I wanna do is to make sure this same combination will never appear again, which will guarantee uniqueness of each minted NFT.

Is something like this even possible?
Ideally I would want to call Chainlink for another set of random numbers in that occasion, but I experimented with that, and fulfillRandomWords fails with another reqeust.

Best Answer

In your description, I think the question is how to get an array of unique 3-digit random numbers with Chainlink VRF effectively.

The brute-force approach is to save the 3-digit numbers in a mapping, and generate the next one. Check if the new one is duplicated, if not, save it in the next index. But since you are paying gasfee for blockchain transactions, the brute-force approach is definitely not a good practice.

My suggestion is first to use a shuffle algorithm to make this happen and the shuffle algorithm I am suggesting here is Fisher–Yates shuffle, which is used by some NFT projects and you can find an explanation here.

In practice, you create an ordered array for 3-digit numbers with length n(n is the number of NFT you are about to mint), then request randomwords from VRF and use them as seeds to shuffle the array.

In the process, function fulfillment is supposed to receive n randomwords from VRF (VRF allows users to request multiple randomwords once), and then these randomwords can be used as seeds to shuffle your n-length array in another tx.

Please be noticed that Shuffle logic is better to be applied in a new function because there is a gas limit in fulfillment function of the VRFConsumer contract.

Related Topic