Understanding NFTs
NFT (Non-Fungible Token) represents unique, indivisible digital assets. Unlike fungible tokens like Bitcoin (where 1 BTC = 1 BTC), NFTs are distinct—think of them as digital collectibles, artwork, or property deeds where each token holds unique attributes.
Key Characteristics:
- Indivisible: Cannot be split into smaller units
- Verifiable Ownership: Blockchain-backed proof of authenticity
- Interoperable: Tradable across compatible platforms like OpenSea
Project Initialization
Tools We'll Use:
- Hardhat: Ethereum development environment
- Solidity: Smart contract programming language
- OpenZeppelin: Secure smart contract libraries
Setup Steps:
mkdir nft-web3-example && cd nft-web3-example
npm init -y
npm install --save-dev hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
npx hardhatSelect "Create a basic sample project" during initialization.
Smart Contract Development
Install OpenZeppelin:
npm install @openzeppelin/contractsContract Structure (FOOL_NFT.sol):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract FoolNFT is ERC721, ERC721URIStorage, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("FoolNFT", "FOOL") {}
function safeMint(address to, string memory uri) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
// Override required functions
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) {
return super.tokenURI(tokenId);
}
}Node Configuration
Using Infura for Rinkeby Testnet:
- Create an account at Infura
- Set up a project with Rinkeby network
Configure
.envfile:PUBLIC_KEY=YOUR_METAMASK_ADDRESS PRIVATE_KEY=YOUR_PRIVATE_KEY INFURA_API=https://rinkeby.infura.io/v3/YOUR_PROJECT_ID NETWORK=rinkeby
Acquiring Test ETH:
Visit Rinkeby Faucet to get test Ether for deployment.
Compiling and Deploying
Compile Contract:
npx hardhat compileDeployment Script (deploy.js):
const hre = require("hardhat");
async function main() {
const FoolNFT = await hre.ethers.getContractFactory("FoolNFT");
const contract = await FoolNFT.deploy();
await contract.deployed();
console.log("Contract deployed to:", contract.address);
}
main().catch(console.error);Run Deployment:
npx hardhat run scripts/deploy.js --network rinkebyMinting NFTs
NFT.Storage Setup:
- Get API key from nft.storage
Update
.env:NFT_STORAGE_TOKEN=YOUR_API_KEY
Minting Script:
const { NFTStorage, File } = require('nft.storage');
const fs = require('fs');
async function mintNFT(imagePath) {
const client = new NFTStorage({ token: process.env.NFT_STORAGE_TOKEN });
const image = new File([await fs.promises.readFile(imagePath)], "nft.png", { type: "image/png" });
const metadata = await client.store({
name: "My NFT",
description: "Unique digital asset",
image: image
});
console.log("Metadata URI:", metadata.url);
}Viewing Your NFT
After minting, find your NFT on:
👉 Discover how to optimize your NFT's visibility
FAQs
What's the gas cost for NFT deployment?
Typical deployment on Rinkeby costs ~0.004 ETH ($10-$20 equivalent in test ETH).
How do I make my NFT collection public?
Add your contract address to NFT marketplaces after verifying the contract on Etherscan.
Can I upgrade my NFT contract later?
Yes, using proxy patterns like OpenZeppelin's Upgradeable Contracts, but requires careful planning.
👉 Learn advanced NFT contract techniques
Next Steps
- Build a frontend with web3-react
- Implement royalty structures
- Create a whitelist system for presales
This guide provides the foundation for creating and deploying NFT contracts. For deeper technical exploration, consider studying ERC-721A and ERC-1155 standards for batch operations.