[ ETERNAL BEINGS / DIRECT CONTRACT MINT ] MAINNET PROCEDURE
Advanced Users / Direct Contract Route

Call the Mint contract directly,
without losing the Reveal.

This route is for users calling through Etherscan, Remix, Foundry, ethers.js, another interface, a multisig, or an agent. The contract can read your wallet state and Commitment, but it cannot recover the original Secret. The caller is responsible for generating, preserving, and revealing the exact Secret.

Visual Route

One address. One epoch. One exact Secret.

Every read and write must use the same Ethereum Mainnet deployment. The address that submits Commit must also submit Reveal and Claim.

00 // VERIFYConfirm Instance

Chain ID 1. Verify deployed bytecode and the official Game address before signing.

chainId = 1
01 // READRead Epoch

Read the current epoch, start block, and immutable timing constants.

currentEpoch()
02 // PHASECheck Commit Window

Commit only while the block offset is below COMMIT_BLOCKS.

offset < 4,800
03 // PRIVATEGenerate Secret

Create one cryptographically random 32-byte value. Never use a timestamp or Math.random().

bytes32 secret
04 // PRIVATESave the Record

Store chain, Game, wallet, epoch, Secret, and Commitment before sending the transaction.

DO NOT PUBLISH
05 // WRITESubmit Commit

Hash wallet + epoch + Secret, simulate, estimate gas, then sign the Commit.

commitMint(commitment)
06 // WAITEnter Reveal

Wait until the current block reaches epochStart + COMMIT_BLOCKS, but not the epoch end.

4,800 ≤ offset < 7,200
07 // WRITEReveal Exact Secret

Use the same address, epoch, and original Secret. Verify the hash before signing.

revealMint(epoch, secret)
08 // WAITEpoch Closes

Claim is available only after the epoch reaches its final block.

offset ≥ 7,200
09 // READCheck Draw State

Read Reveal count, claim limit, claimed count, and your claimed status.

epochClaimLimit(epoch)
10 // WRITEClaim Result

Simulate first. If selected and capacity remains, Claim mints the Being.

claimMint(epoch)
11 // VERIFYConfirm Outcome

Verify the receipt, events, ownership, token ID, Being state, and on-chain metadata.

BeingMinted + Transfer
PUBLIC READ / CHECKPRIVATE OFF-CHAIN DATAGAS-PAID WRITE
Commitment Formula

The wallet address is part of the hash

commitment = keccak256( abi.encodePacked(walletAddress, epoch, secret) )

ADDRESS

Use the exact address that will send commitMint. Address A cannot Reveal Address B's Commitment.

EPOCH

Use the epoch returned immediately before Commit. A Secret committed for Epoch N cannot Reveal Epoch N+1.

SECRET

Use exactly 32 bytes. Preserve every byte unchanged until the Reveal transaction confirms.

Never submit the raw Secret to commitMint. Commit accepts only the Commitment hash. Publishing the Secret before Reveal defeats the concealment step.
Direct ethers.js Example

Generate locally, simulate, then sign

import { BrowserProvider, Contract, hexlify, randomBytes, solidityPackedKeccak256 } from "ethers"; const GAME = "0xC6D9Ea961C1E1E5F99D36970FcC824b8faA144f3"; const provider = new BrowserProvider(window.ethereum); await provider.send("eth_requestAccounts", []); const signer = await provider.getSigner(); const wallet = await signer.getAddress(); const game = new Contract(GAME, [ "function currentEpoch() view returns (uint256)", "function commitments(uint256,address) view returns (bytes32)", "function commitMint(bytes32)", "function revealMint(uint256,bytes32)", "function claimMint(uint256)" ], signer); const epoch = await game.currentEpoch(); const secret = hexlify(randomBytes(32)); const commitment = solidityPackedKeccak256( ["address", "uint256", "bytes32"], [wallet, epoch, secret] ); // Save { chainId, GAME, wallet, epoch, secret, commitment } // in protected local storage BEFORE sending Commit. await game.commitMint.staticCall(commitment); const commitReceipt = await (await game.commitMint(commitment)).wait(); // During Reveal, load the exact stored record and verify it first. const onchain = await game.commitments(epoch, wallet); const expected = solidityPackedKeccak256( ["address", "uint256", "bytes32"], [wallet, epoch, secret] ); if (onchain !== expected) throw new Error("Secret mismatch — stop"); await game.revealMint.staticCall(epoch, secret); const revealReceipt = await (await game.revealMint(epoch, secret)).wait(); // After the epoch closes, simulate Claim before sending it. await game.claimMint.staticCall(epoch); const claimReceipt = await (await game.claimMint(epoch)).wait();
Never place a private key, seed phrase, raw Secret, or decrypted keystore in website code, source control, a command line, screenshots, social posts, or agent chat. Use an injected wallet, hardware wallet, multisig, or protected local signer.
Etherscan / Manual Route

Etherscan does not generate or remember your Secret

  1. Open the verified contract and confirm the address exactly.
  2. Use Read Contract to obtain currentEpoch(), epochStart(epoch), COMMIT_BLOCKS(), and EPOCH_BLOCKS().
  3. Generate the 32-byte Secret and Commitment offline with a trusted tool.
  4. Save the complete private record before connecting Etherscan.
  5. Under Write Contract, connect the correct wallet and call commitMint(commitment).
  6. During Reveal, reconnect the same address and call revealMint(epoch, secret).
  7. After epoch close, call claimMint(epoch). A successful Reveal does not guarantee selection when oversubscribed.
If a direct caller loses a randomly generated Secret, neither Ethereum, the contract, Etherscan, nor the official website can reconstruct it from the Commitment.
Multiple Addresses

Each wallet follows an isolated state machine

Stored and checked per addressWhy it cannot mix
commitments(epoch, wallet)The mapping is keyed by both epoch and address.
revealed(epoch, wallet)Reveal is recorded only for the caller whose Commitment matches.
claimedEpoch(epoch, wallet)Claim status belongs to that address and epoch.
hasMintedBeing(wallet)Each address can successfully Mint only one lifetime Being.
Address A + Epoch N + Secret A → Commitment A Address B + Epoch N + Secret B → Commitment B Commitment A ≠ Commitment B

When switching accounts, re-read all state for the newly selected address. Never reuse another address's Secret record. A Safe or other smart-contract wallet must execute Commit, Reveal, and Claim through that same contract wallet address.

Failure Prevention

Stop before signing when any check fails

BEFORE COMMIT

  • Correct chain and Game address.
  • Commit window is open.
  • No existing current-epoch Commitment.
  • Wallet has not already Minted.
  • Secret record is safely stored.

BEFORE REVEAL

  • Reveal window is open.
  • Same wallet and epoch.
  • Recomputed hash equals on-chain Commitment.
  • revealed is false.
  • Simulation succeeds.

BEFORE CLAIM

  • Epoch is complete.
  • Reveal succeeded.
  • Claim has not already executed.
  • Wallet has not already Minted.
  • Simulation confirms eligibility.
Contract state is the source of truth for phase, Commitment, Reveal, Claim, supply, and ownership. The Secret is intentionally private off-chain input until Reveal.