Plan your NFT collection deployment. Choose options, estimate costs, get a step-by-step guide.
Deployment Options
Cost Estimate
Deployment Gas:2,500,000 gas
Gas Price:30 Gwei
Total Cost:
0.0750 ETH
~$225.00 USD
Timeline Estimate
2-6 hours
From start to deployment
Varies based on: contract complexity, testing thoroughness, network congestion
Deployment Checklist
1.Write and test smart contract (Hardhat/Foundry)
2.Prepare metadata and upload to IPFS
3.Pin metadata folder to IPFS (Pinata/NFT.Storage)
4.Deploy contract to Ethereum Mainnet
5.Verify contract on block explorer
6.Test minting on testnet first
7.List on marketplaces (OpenSea, etc.)
Security Checklist
✓Reentrancy protection (use OpenZeppelin)
✓Access control for admin functions
✓Proper randomness (use Chainlink VRF if needed)
✓Gas-efficient loops (avoid unbounded iterations)
✓Pausable functionality for emergencies
✓Audit critical functions or get external review
Network Comparison
Ethereum Mainnet
~30 Gwei
Audience: Largest • Marketplaces: All
Base
~0.1 Gwei
Audience: Growing fast • Marketplaces: OpenSea, Zora
Arbitrum
~0.2 Gwei
Audience: Large • Marketplaces: OpenSea, Treasure
Polygon
~0.5 Gwei
Audience: Large • Marketplaces: OpenSea, Rarible
Recommended Approach
ERC-721 + IPFS
Gas: ~2,500,000 • Time: 2-4 hours
Pros:
• Standard approach
• Low deployment cost
• Decentralized storage
Cons:
• IPFS gateways can be slow
• Metadata not on-chain
ERC-721 + On-Chain SVG
Gas: ~4,000,000 • Time: 4-6 hours
Pros:
• Fully on-chain
• No external dependencies
• Permanent
Cons:
• Higher deployment cost
• Limited to SVG
• Gas per mint
ERC-721A (Azuki)
Gas: ~2,800,000 • Time: 3-5 hours
Pros:
• Optimized batch minting
• Standard compliant
• Lower mint costs
Cons:
• Slightly higher deploy cost
• More complex
Example Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyNFT is ERC721, Ownable {
uint256 public nextTokenId;
string public baseURI;
constructor(string memory _baseURI)
ERC721("MyNFT", "MNFT")
Ownable(msg.sender)
{
baseURI = _baseURI;
}
function mint(address to) external onlyOwner {
_safeMint(to, nextTokenId);
nextTokenId++;
}
function _baseURI() internal view override returns (string memory) {
return baseURI;
}
function tokenURI(uint256 tokenId)
public view override returns (string memory)
{
require(ownerOf(tokenId) != address(0), "Token does not exist");
return string(abi.encodePacked(baseURI, tokenId.toString(), ".json"));
}
}