Search code examples
chainlink

What is the best practice to get history random number in Chainlink VRF?


In the project, I rely on Chainlink VRF to get a random word to decide a raffle winner, but I failed to keep the minimum LINK balance in my VRF subscription so all requests are pending. (I thought transactions are not sent successfully so I called the function several times by mistake).

After I transfer some Link tokens to my VRF subscription, all the random numbers are sent to my contract. In the scenario, I only need the first one of these random words for the raffle, but I am not sure if the random word stored in the smart contract now is the first one.

If transactions based on random words did not succeed for some reason, where to find random words in history so that these transactions can be re-sent?

So my question is:

What is the best practice to get history random words generated by Chainlink VRF?

Thanks in advance.


Solution

  • After doing some research, I will answer the question.

    The best practice is to keep random words in an array in your smart contract or you can add an event in fulfillment function in your consumer smart contract to record requestId and corresponding random words.

    But if there is no event or other variables to record the random words in your smart contract, you can do the following:

    1. Get requestId and randomness from event RandomWordsFulfilled in smart contract VRFCoordinatorV2, it can be found in the transaction sent by VRF node.
    emit RandomWordsFulfilled(requestId, randomness, payment, success);
    
    1. Get numWords from event RandomWordsRequested in VRFCoordinatorV2 smart contract.
        emit RandomWordsRequested(
          keyHash,
          requestId,
          preSeed,
          subId,
          requestConfirmations,
          callbackGasLimit,
          numWords,
          msg.sender
        );
    
    1. Random words are generated by randomness and numWords in the following logic that is defined in function fulfillRandomWords in smart contract VRFCoordinatorV2. You can use the same logic to get the history random words.
    for (uint256 i = 0; i < numWords; i++) {
      randomWords[i] = uint256(keccak256(abi.encode(randomness, i)));
    }