The Batch Reveal Mechanism
July 23rd, 2022

The way an NFT collection reveals its art is an essential part of its launch sequence, and success or failure in this area can set the tone for a collection’s reputation. We’ve all seen the damage done to a collection’s reputation by a botched reveal or a sniped pre-reveal rare. Projects can become victims of their own hype such that nefarious actors have a financial incentive to take advantage of vulnerabilities by trying to snipe rare outputs before they’ve been revealed. We’ve also witnessed negative feedback loops, when a slow mint-out forces a team to choose between waiting to reveal the NFTs and cutting off the supply in order to reveal now, due to contract-level assumptions around the reveal. As such, when two of our founders, 0xetash and 0xtygra, were developing the smart contract for the Good Minds launch, we wanted to create a reveal mechanism that was as fair and progressive as possible. The rest of this post explores what we call the “Fair, Progressive Batched Reveal Mechanism” in hopes it will aid future projects.

Fair

For us, a “fair” reveal mechanism is one where no one, neither the team, nor a technical individual, nor anyone else could use their knowledge to affect what metadata their token is assigned.

The most common type of “unfair” reveal mechanism we see is one where individuals or the team have prior knowledge as to what metadata any given token will have, sometimes before the reveal, and sometimes even before that token has minted. This allows people to snipe rare outputs or trade based on insider information.

The most common reasons this happens are:

  • The metadata is uploaded in such a way that one can query the metadata of tokens ahead of the mint/reveal, or
  • The metadata of individual tokens is known in advance by the team

With respect to the latter, in the vast majority of cases, it isn’t a problem due to the team being entirely trustworthy. For us, “vast majority” is not convincing enough, and our concerns are well-founded as there are still numerous cases of even one team member acting nefariously, usually by buying ultra-rare tokens pre-reveal.

One of the most common approaches to ensuring a “fair” reveal is to use a verifiable random number to shuffle all the metadata at the moment of reveal. A well-known example is the 3Landers contract.

At a high level, N tokens (let’s say 10,000) are minted, and the 10,000 associated metadata files are uploaded to a decentralised storage solution, like IPFS. The location of the metadata would look like so: ipfs://<root content hash for all the metadata>/<N>, such that the 100th metadata, if the collection is 0-indexed, is at ipfs://<root hash>/99.

Before the reveal, the contract returns the default metadata, usually containing a placeholder image or GIF. Then, at the moment of the reveal, to ensure fairness, the contract requests a verifiable random value, usually via Chainlink VRF (as is our case), and uses this data to shuffle all of the metadata before assigning it. The end result is such that it is actually very unlikely for token N to have metadata N, due to the shuffling, and there is no way for anyone to know ahead of time which of the 10,000 distinct metadata a token will have.

This approach allows for the contract to reveal its NFTs once, and only once, and when it reveals, it sets the metadata for every NFT in the collection. This leads us to the next part of our solution.

Progressive

Our second requirement was that the reveal had to be progressive such that it could function regardless of market conditions / the rate at which the project mints. It’s no secret that cryptocurrencies, and especially NFTs, are a volatile asset class, with the sentiment of the entire market changing daily.

The specific shuffle mechanism we explored earlier relies on all tokens being minted to ensure a truly fair reveal. This is due to there being a single piece of random data to seed the shuffle for the whole collection. If this shuffle reveal were to be called before the project minted out, and the data were stored publicly, un-minted tokens’ metadata would be known ahead of time. This works perfectly when a project mints out quickly but could put a team in a tough spot if a project were to mint out slowly over a period of weeks. Do you reveal before everything has minted out and have un-minted tokens be potentially vulnerable? Or do you pause the mint and lower your supply in order to have a truly fair reveal? These are just two options available to a team in this position, but suffice it to say that it’s not an ideal situation in which to be.

A decision a number of teams have made in order to solve for this problem is to instead serve their data from a custom server. If the data is coming from a server run by the team, rather than a decentralised storage solution such as IPFS or Arweave, then they can write code that wouldn’t allow you to query the server for the metadata of a token that hasn’t yet been minted. While this solution allows for each token to reveal immediately upon minting, it runs counter to the idea of a “fair” reveal as the team has prior knowledge regarding the metadata of individual tokens.

Our solution

Enter the “Fair, Progressive Batched Reveal Mechanism” as implemented by Silika Studio in the Good Minds contract.

It’s similar to the “shuffle” approach as outlined before, but instead of shuffling the whole collection’s metadata, this approach allows us to shuffle just the NFTs that are currently unrevealed. When a new batch of NFTs needs to be revealed, the metadata between the lowest and highest tokenID of that batch is shuffled with fresh random data from Chainlink VRF, and then the metadata is assigned. By getting a new random seed for each new batch, it’s provably impossible to know an unrevealed token’s metadata before reveal.

This approach comes with a great degree of flexibility for teams too, as each reveal incurs only a marginal cost in gas fees / $LINK. Is it minting out quickly? Great, you may only need to reveal once upon minting out. Are things moving slowly but surely? Maybe you reveal every 500 tokens, or every 2 days and create a community event around it. Regardless of your decision, the important benefit is that you actually can decide.

We experienced the benefits of this flexibility firsthand. Before the allowlist and public mint, we minted 300 Good Minds NFTs to be held by the team, 150 of which to be added to an NFTX pool that would go live during the launch. We specifically wanted to reveal these before the allowlist and public mints, to provide prospective minters a glimpse of what the collection looks like. Without the progressive nature of our mint mechanic, this wouldn’t have been possible.

Shuffling the metadata results in the tokenID and tokenURI almost never matching, e.g. tokenID 10 could map to the tokenURI ipfs://bafyasdfasfasf/200. This isn’t a critical issue, but as developers, we’ve found that there are benefits to a matching tokenID and tokenURI, e.g. tokenID 10 has tokenURI ipfs://bafyasdfasfasf/10. NFT applications, like marketplaces and ranking platforms, must resolve all tokenURIs to completely index a collection. If the tokenID and tokenURI don’t match, then the application is forced to call tokenURI once for every NFT in the collection. Whereas if the tokenID and tokenURI do match, then one can call baseURI once, store the base URI, and append the tokenID to the base URI to form a token’s tokenURI.

To solve this, we added an isShuffled boolean to the contract. If it’s true, then tokenURI will perform all the shuffle logic and return the resultant random ID. If it’s false (signifying that we’ve “unshuffled” the metadata), then it simply returns the baseURI with the appended tokenID. To “unshuffle” the data, we need to upload a new folder to IPFS that has the metadata matching the tokenID. Using our tokenID 10 example from before, we’d just have to rename 200.json to 10.json in the folder. Note: no metadata of any NFT will change as a result of this. In the coming weeks, we will formally announce the unshuffle date, as well as publish a provenance hash for the metadata before the unshuffle.

Good Minds Batch Reveal
Good Minds Batch Reveal

Conclusion

As a web3 dev studio, one of our core tenets is building trustless systems. Individuals shouldn’t need to trust (often pseudonymous) teams when we have all the tools at our disposal to build trustless systems.

We were very happy with the result of our batched shuffle reveal mechanism. It’s both provably fair, while still being flexible to enable teams to react to sensitive market conditions. We intend to use this reveal approach for future mints.

If you’re looking for a team of devs with these values at their core, reach out to Silika Studio! Similarly, if you’ve implemented something similar, we’d love to chat and share our experiences 🙂

Subscribe to Silika Studio
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from Silika Studio

Skeleton

Skeleton

Skeleton