1

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.

2 Answers 2

2

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.

4
  • Frank, thank you for your answer, this would probably help and solve this problem, but unfortunately I simplified this problem that I have. In real case I have 6 numbers with different ranges, so if I will shuffle this array there would be the risk that some layers wouldn't match and it will revert. But its useful and worth to know that for the future projects, thank you.
    – BlackH3art
    Commented Aug 6, 2022 at 8:18
  • You are welcome @BlackH3art , I think the 6 number should be the same, can you create an array for 6-digit numbers like 111111 - 999999 and remove all numbers with any digit 0. Then you can shuffle this array, and you can get unique random 6-digit numbers in your array.
    – Frank Kong
    Commented Aug 6, 2022 at 12:28
  • what I meant by that is that I have range between 1-7 for the first number, and 1-10 range for second number, and 1-15 range for third and so on. In this case if I will shuffle those numbers, there's risk that some numbers won't match my layers. Or am I misunderstanding what you saying? In that case could you give me some code example? Thank you Frank.
    – BlackH3art
    Commented Aug 7, 2022 at 9:29
  • @BlackH3art I see, I misunderstood your first comment. If so, the shuffle is not a solution since there is a risk some numbers won't match the layer as you said. I will think about it and update the answer if I have a good idea.
    – Frank Kong
    Commented Aug 7, 2022 at 9:48
0

I have the save issue - get random unique numbers from an oracle (Chainlink).

I have broken this process down into 4 steps:

  1. request random numbers from Chainlink VRF,
  2. fulfill the random number request (comes from Chainlink VRF),
  3. shuffle the token IDs for airdrop,
  4. perform the airdrop

1 - Among other checks, verifications etc., I request a random numbers from VRF;

2 - fulfillRandomWords is triggered by Chainlink;

3 - shuffleVRFRequestId - I shuffle the result for the VRF result. Here I solve the problem of duplicate numbers because I need to use token ids that must be unique. Please see my code snippet as a screenshot.

4 - perform airdrop in separate function.

The main reason why this process should be separated is gas limits.

Hope my answer helps or... :) I will get valuable comments & suggestions on it.

shuffle function

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.