NFT Standards (ERC-721 & ERC-1155)
Create and deploy non-fungible tokens (NFTs) on Tetreum Testnet using industry-standard protocols.
Non-Fungible Tokens (NFTs) are unique digital assets that represent ownership of specific items or content on the blockchain. Unlike ERC-20 tokens, each NFT has distinct properties and value.
ERC-721 (Single NFTs)
- • Each token is completely unique
- • One token per transaction
- • Perfect for art, collectibles
- • Simple ownership model
- • Most widely adopted standard
ERC-1155 (Multi-Token)
- • Multiple token types in one contract
- • Batch transfers for efficiency
- • Gaming items, utility tokens
- • Fungible and non-fungible support
- • Gas-efficient operations
Basic ERC-721 NFT contract using OpenZeppelin:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
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 MyNFT is ERC721, ERC721URIStorage, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
uint256 public constant MAX_SUPPLY = 10000;
uint256 public constant MINT_PRICE = 0.01 ether;
constructor() ERC721("MyNFT Collection", "MYNFT") {}
function mintNFT(address recipient, string memory tokenURI)
public onlyOwner returns (uint256) {
require(_tokenIds.current() < MAX_SUPPLY, "Max supply reached");
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
function publicMint(string memory tokenURI) public payable returns (uint256) {
require(msg.value >= MINT_PRICE, "Insufficient payment");
require(_tokenIds.current() < MAX_SUPPLY, "Max supply reached");
return mintNFT(msg.sender, tokenURI);
}
function withdraw() public onlyOwner {
payable(owner()).transfer(address(this).balance);
}
// Override required by Solidity
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);
}
}Multi-token standard contract for gaming and utility NFTs:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract GameItems is ERC1155, Ownable {
using Strings for uint256;
// Token IDs
uint256 public constant SWORD = 1;
uint256 public constant SHIELD = 2;
uint256 public constant POTION = 3;
mapping(uint256 => uint256) public tokenSupply;
mapping(uint256 => uint256) public maxSupply;
constructor() ERC1155("https://api.gameserver.com/metadata/{id}.json") {
// Set max supplies
maxSupply[SWORD] = 1000;
maxSupply[SHIELD] = 2000;
maxSupply[POTION] = 10000;
// Mint initial supply to owner
_mint(msg.sender, SWORD, 100, "");
_mint(msg.sender, SHIELD, 200, "");
_mint(msg.sender, POTION, 1000, "");
tokenSupply[SWORD] = 100;
tokenSupply[SHIELD] = 200;
tokenSupply[POTION] = 1000;
}
function mint(address to, uint256 id, uint256 amount) public onlyOwner {
require(tokenSupply[id] + amount <= maxSupply[id], "Exceeds max supply");
_mint(to, id, amount, "");
tokenSupply[id] += amount;
}
function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts)
public onlyOwner {
for (uint i = 0; i < ids.length; i++) {
require(tokenSupply[ids[i]] + amounts[i] <= maxSupply[ids[i]],
"Exceeds max supply");
tokenSupply[ids[i]] += amounts[i];
}
_mintBatch(to, ids, amounts, "");
}
function uri(uint256 tokenId) public view override returns (string memory) {
return string(abi.encodePacked(
"https://api.gameserver.com/metadata/",
tokenId.toString(),
".json"
));
}
}NFT metadata follows a standard JSON format for interoperability:
Standard Metadata Format
{
"name": "Amazing NFT #1",
"description": "This is an amazing NFT with unique properties",
"image": "https://ipfs.io/ipfs/QmYourImageHash",
"external_url": "https://yourwebsite.com/nft/1",
"attributes": [
{
"trait_type": "Rarity",
"value": "Legendary"
},
{
"trait_type": "Power",
"value": 95,
"max_value": 100
},
{
"trait_type": "Element",
"value": "Fire"
}
]
}Storage Options
IPFS (Recommended)
Decentralized, immutable storage for true NFT permanence
Arweave
Permanent storage with one-time payment model
Cloud Storage
Traditional hosting (less decentralized)
On-chain SVG
Fully on-chain generative art and metadata
Royalties (EIP-2981)
Automatic creator royalties on secondary sales
function royaltyInfo(uint256, uint256 salePrice)Enumerable Extension
Query tokens by owner and iterate collections
ERC721EnumerableBurnable Tokens
Allow token holders to destroy their NFTs
ERC721BurnablePausable Transfers
Emergency pause functionality for security
ERC721PausableLaunch Your NFT Collection
Create unique digital assets and build thriving NFT communities on Tetreum Testnet.