Welcome to a comprehensive guide on creating non-fungible tokens (NFTs) using the ERC-721 standard on Ethereum. This tutorial will walk you through the entire process—from understanding the basics to deploying your own NFT collection on the Sepolia testnet and viewing it on OpenSea.
Table of Contents
- Understanding Tokens
- What is the ERC-721 Standard?
- Building a Basic ERC-721 Contract
- Adding Metadata to Your NFTs
- Advanced Features: URI Storage, Burnable, Pausable, Enumerable
- Deploying and Testing Your Contract
- FAQs
- Further Exploration
- Conclusion
Understanding Tokens
Tokens represent digital or physical assets on the blockchain. They fall into two categories:
- Fungible Tokens: Interchangeable (e.g., cryptocurrencies like ETH or stablecoins like USDT).
- Non-Fungible Tokens (NFTs): Unique (e.g., digital art, collectibles, or real-world assets like real estate).
👉 Learn more about fungible vs. non-fungible tokens
What is the ERC-721 Standard?
The ERC-721 standard enables the creation of NFTs on Ethereum by defining a set of rules for token interactions, including:
- Ownership tracking (
ownerOf). - Transfers (
safeTransferFrom). - Approvals (
approve,setApprovalForAll).
Key methods:
function balanceOf(address _owner) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;Events:
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);OpenZeppelin’s ERC721 contract handles these implementations.
Building a Basic ERC-721 Contract
Step 1: Use OpenZeppelin’s Solidity Wizard
Select ERC721 and enable:
- Mintable
- Auto Increment Ids
- Ownable
Customize the contract:
contract FootballPlayers is ERC721, Ownable { uint256 private _nextTokenId; constructor() ERC721("Football Players", "FTP") Ownable(msg.sender) {} function safeMint(address to) public onlyOwner { uint256 tokenId = _nextTokenId++; _safeMint(to, tokenId); } }
Step 2: Set Up a Hardhat Project
npm init -y
npm install -D hardhat @nomicfoundation/hardhat-ignition-ethers
npx hardhat init # Choose TypeScriptConfigure hardhat.config.ts for Sepolia:
networks: {
sepolia: {
url: process.env.INFURA_SEPOLIA_ENDPOINT,
accounts: [process.env.PRIVATE_KEY]
}
}Adding Metadata to Your NFTs
Store NFT metadata (name, image, description) off-chain using IPFS:
- Upload images and JSON files to NFT.Storage.
Link metadata via
tokenURI:function _baseURI() internal pure override returns (string memory) { return "ipfs://YOUR_FOLDER_CID/"; } function tokenURI(uint256 tokenId) public view override returns (string memory) { return string(abi.encodePacked(_baseURI(), tokenId.toString(), ".json")); }
Example JSON:
{
"name": "Football Players #0",
"description": "Italian football player",
"image": "ipfs://IMAGE_CID"
}Advanced Features
Extend functionality with OpenZeppelin’s extensions:
- URI Storage: Store per-token metadata.
- Burnable: Allow token destruction (
burn). - Pausable: Freeze transfers (
pause/unpause). - Enumerable: Track all tokens (
totalSupply).
Updated contract:
contract FootballPlayers is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {
function safeMint(address to, string memory uri) public onlyOwner {
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
// Override required methods (e.g., _update, supportsInterface)
}Deploying and Testing Your Contract
- Compile:
npx hardhat compile Test:
npx hardhat test test/FootballPlayers.ts --typecheckDeploy to Sepolia:
npx hardhat ignition deploy ignition/modules/FootballPlayers.ts --network sepolia- Verify on OpenSea.
FAQs
Q1: What’s the difference between ERC-721 and ERC-20?
- ERC-20: Fungible tokens (e.g., cryptocurrencies).
- ERC-721: Non-fungible tokens (unique assets).
Q2: How do I store NFT metadata cheaply?
Use IPFS for decentralized, cost-effective storage.
Q3: Can I update metadata after minting?
No, IPFS data is immutable. Plan metadata carefully before deployment.
Further Exploration
Conclusion
You’ve now learned how to:
- Deploy an ERC-721 contract.
- Add metadata via IPFS.
- Extend functionality with OpenZeppelin.
- Test and deploy on Ethereum.
Happy coding! For questions, reach out via GitHub.
This version:
- Follows SEO best practices (keyword integration, structured headings).
- Removes redundant/ads.
- Adds FAQs and engaging anchor texts.