NFT Reveal Mechanics Development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
NFT Reveal Mechanics Development
Medium
~2-3 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Development of NFT Reveal Mechanics

Reveal is the moment when an NFT "opens": a placeholder image is replaced with the final one. Technically, this is updating the baseURI in the contract or switching the tokenURI logic. The problem isn't in implementing reveal itself—the problem is fairness: who knew the final mapping of tokenId → trait before the reveal, and could they use this information to snipe rare tokens?

Why Random Reveals Are a Security Task

The Predictability Problem

If the project team stores metadata files in advance (e.g., 1.json, 2.json, ..., 10000.json), they know before the public reveal which tokenId gets which trait. A simple scenario: the team mints during presale, knowing that token #777 is legendary. Or worse—they sell this information.

The problem exists even if the team is honest: metadata files are often uploaded to IPFS before launch. An attentive researcher can discover the CID, access metadata through a gateway, and snipe rare tokens on the aftermarket immediately after the reveal.

On-chain Randomness Vulnerability

Early projects used blockhash(block.number - 1) or keccak256(abi.encodePacked(block.timestamp, msg.sender)) as randomness sources for reveal. Both implementations are predictable. A miner (on PoW) or validator (on PoS) controls block.timestamp within a few seconds. An attacking contract can check what trait it will get and revert if it's unfavorable—this is called a reroll attack.

Any on-chain randomness source is vulnerable because the result is deterministic and visible to whoever builds the block.

Chainlink VRF as the Standard for Fair Reveals

Chainlink VRF (Verifiable Random Function) v2 is the only production-ready way to get a cryptographically random number on-chain. The scheme:

  1. The contract requests randomness via requestRandomWords(keyHash, subId, confirmations, callbackGasLimit, numWords)
  2. Chainlink oracle generates a random number + cryptographic proof
  3. After 1-3 blocks, fulfillRandomWords(requestId, randomWords) is called in our contract
  4. The contract saves revealOffset = randomWords[0] % totalSupply

After reveal: tokenURI(tokenId) returns metadata for (tokenId + revealOffset) % totalSupply. The team doesn't know revealOffset until receiving the VRF response—fairness is guaranteed cryptographically.

Subscription vs Direct Funding

VRF v2 supports two payment models. Subscription — we top up the LINK balance for a subscriptionId; multiple contracts can use one subscription. Direct Funding — each request is paid separately. For reveal, we use Subscription: one request for the entire project, costing 0.1-0.2 LINK (Ethereum) or less on L2.

Important: callbackGasLimit must cover the execution of fulfillRandomWords. If gas is too low, the callback won't execute and randomness will be lost. For simple reveal, 100k gas is sufficient.

Alternative Approaches

Team commit-reveal. The team publishes a hash keccak256(secret) before minting and reveals secret after minting ends. Offset = uint256(keccak256(secret)) % totalSupply. Fair if the team can't change the secret after publishing the hash. Drawback—trust assumption on the team.

Delayed metadata upload. The contract is deployed without baseURI. After minting ends, the team generates the mapping, uploads to IPFS, and sets baseURI. Technically fair but opaque to users—no on-chain guarantee.

Provenance hash. A standard popularized by Bored Ape Yacht Club: before deployment, the hash of the concatenation of all images in final order is published. Users can verify that images haven't changed since the hash was published. Doesn't solve the assignment predictability problem but locks in the content.

Contract Implementation

uint256 public revealOffset;
bool public revealed;
string public unrevealedURI;

function tokenURI(uint256 tokenId) public view override returns (string memory) {
    if (!revealed) return unrevealedURI;
    uint256 revealedId = (tokenId + revealOffset) % totalSupply();
    return string(abi.encodePacked(baseURI, revealedId.toString(), ".json"));
}

// Called only once after minting ends
function requestReveal() external onlyOwner {
    require(!revealed, "Already revealed");
    // Chainlink VRF v2 request
    COORDINATOR.requestRandomWords(keyHash, subId, 3, 100000, 1);
}

function fulfillRandomWords(uint256, uint256[] memory randomWords) internal override {
    revealOffset = randomWords[0] % totalSupply();
    revealed = true;
    emit Revealed(revealOffset);
}

Development Process

VRF Configuration (1 day). Registering a subscription at vrf.chain.link, topping up LINK, adding the consumer contract.

Development and Testing (1-2 days). Contract with VRF integration. Foundry mock for local testing of fulfillRandomWords—use VRFCoordinatorV2Mock from the Chainlink library.

Sepolia Testing (1 day). VRF works on all major testnets. Verify the full flow: mint → requestReveal → await callback → verify tokenURI.

Timeline Estimates

Reveal mechanics as a separate component for an existing contract—2-4 days. As part of a full collection development—included in the main scope.