Web37 min read

NFT Development

Build NFT collections with ERC-721 and ERC-1155 standards, on-chain metadata, allowlists, reveal mechanics, and royalty enforcement.

nfterc721web3solidity

NFTs (Non-Fungible Tokens) represent unique digital ownership on the blockchain. Building an NFT collection requires knowledge of ERC-721/1155 standards, gas optimization (ERC-721A), secure minting mechanics, reveal patterns, and royalty standards.

Use ERC-721A for large collections (saves 60%+ gas on batch mints). Use Merkle trees for allowlists. Implement commit-reveal for fair reveals. Set royalties via ERC-2981. Test all mint scenarios before deploying.

Workflow

  1. Choose ERC-721 vs ERC-721A vs ERC-1155Wrong standard wastes gas or limits functionality for your collection type.
  2. Implement allowlist with Merkle treesStoring allowlist on-chain costs thousands in gas; Merkle proofs verify off-chain list with minimal on-chain state.
  3. Build mint mechanics: phases and pricingMost collections have multiple mint phases (OG allowlist → public); managing them in one contract reduces deployment complexity.
  4. Implement reveal mechanicsUnrevealed collections prevent sniping (buying rares before reveal); fair reveal requires on-chain randomness commitment.
  5. Set royalties with ERC-2981ERC-2981 is the standard royalty interface; marketplaces that respect it will route royalties to your contract.

Output Format

ERC-721A contract with Merkle allowlist, phase management, Chainlink VRF reveal, ERC-2981 royalties, Hardhat tests for all mint scenarios.

Examples

ERC-721A with allowlist: `function allowlistMint(uint256 qty, bytes32[] calldata proof) external payable { require(phase == Phase.ALLOWLIST); require(MerkleProof.verify(proof, merkleRoot, keccak256(abi.encodePacked(msg.sender)))); require(msg.value >= qty * PRICE); _mint(msg.sender, qty); }`
Royalty setup: `constructor() ERC721A("Collection", "COLL") { _setDefaultRoyalty(msg.sender, 500); }`
Reveal URI: `function tokenURI(uint256 id) public view override returns (string memory) { return revealed ? string.concat(baseURI, ((id + offset) % MAX_SUPPLY).toString(), ".json") : preRevealURI; }`

Edge Cases & Gotchas

  • Marketplace royalty enforcement: OpenSea moved to voluntary royalties; consider on-chain enforcement via operator filtering (ClosedSea or custom blocklist)
  • Mint bot attacks: add per-tx limits and require proofs; bots can still operate at scale if mint is profitable enough
  • ERC-721A token ID shifting: token IDs start at 0 by default; override `_startTokenId()` to return 1 if your frontend expects 1-indexed IDs

When to Break These Rules

  • For small 1:1 art collections (<100 pieces), simple ERC-721 is cleaner than ERC-721A; the gas optimization only matters at scale.

Reference Files

  • ERC-721A: https://www.erc721a.org/
  • OpenZeppelin ERC-721: https://docs.openzeppelin.com/contracts/4.x/erc721
  • Chainlink VRF: https://docs.chain.link/vrf/
  • ERC-2981 Royalties: https://eips.ethereum.org/EIPS/eip-2981

More skills in this library

Browse all technical skills - Mobile, AI/ML, Web, Backend, Design, and Product.