This repository contains information on the randomization process Orange Comet used for Anthony Hopkins - The Eternal
.
Why is randomization transparency important? In collections where specific tokens have attributes designed to give more rarity, the community may designate such tokens as having higher value. Transparency in any "shuffle" or added utility assures the community that the process is fair to all who participate.
After reviewing various solutions, we selected Chainlink VRF because itβs based on cutting-edge academic research, supported by a time-tested oracle network, and secured through the generation and on-chain verification of cryptographic proofs that prove the integrity of each random number supplied to smart contracts.
By integrating the industry-leading decentralized oracle network, we now have access to a tamper-proof and auditable source of randomness needed to help randomize the unique characteristics of the NFTs for the art reveal and to help randomize the distribution of rewards to NFT owners. Ultimately this creates a more exciting and transparent user experience, as users can have high confidence that the randomness used in the art reveal and winner selection process is provably fair.
For additional information check out our blog post on The Eternal Collection Uses Chainlink VRF to Help Power Fair NFT Reveal and Winner Selection
The original metadata files (1000 in total) are contained in the sorted-metadata directory. These files were sorted alphabetically by group title and number. Orange Comet used Chainlink's VRF product to generate a random number to seed the shuffle method.
The RandomNumberGenerator contract makes the requests for the random number with parameters for tracking the purpose of the request. The method requestRandomWords
is outlined below:
/**
* @notice Makes a random request
* Assumes the subscription is funded sufficiently; "Words" refers to unit of data in Computer Science
*
* @param partnerContract the address of the partner contract
* @param totalEntries the total number of entries to randomize
* @param totalSelections the number of selections to return
* @param title the title used to write the logs
*/
function requestRandomWords(
address partnerContract,
uint32 totalEntries,
uint32 totalSelections,
string calldata title
) external onlyOwner {
// Will revert if subscription is not set and funded.
uint256 requestId = COORDINATOR.requestRandomWords(
_keyHash,
_subscriptionId,
REQUEST_CONFIRMATIONS,
CALLBACK_GAS_LIMIT,
NUM_WORDS
);
requests[requestId] = Params(
partnerContract,
totalEntries,
totalSelections,
title
);
}
Once Chainlink's oracles have generated a random number, the fulfillRandomWords
function will be called with the initial request ID and resulting randomWords
. The result will emit a ReturnedRandomWord
event in order to signal the generator was successfully called. An example of this can be viewed on Etherscan
/**
* @notice Callback function used by VRF Coordinator
*
* @param requestId - the requestId from the VRF Coordinator
* @param randomWords - array of random results from VRF Coordinator
*/
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords)
internal
override
{
emit ReturnedRandomWord(randomWords[0], requestId, requests[requestId]);
}
For convenience an application was developed to take a fulfillRandomWords
transaction (implemented by an Orange Comet RandomNumberGenerator contract), parse the logs and shuffle the results using the shuffle method. The web application also allows us to disqualify certain tokens based on conditions such as already existing utility and flagged wallets.