Standard dei token non fungibili ERC-721
Ultimo aggiornamento della pagina: 25 febbraio 2026
Introduzione
Cos'è un token non fungibile?
Un token non fungibile (NFT) è utilizzato per identificare qualcosa o qualcuno in modo unico. Questo tipo di token è perfetto per essere utilizzato su piattaforme che offrono oggetti da collezione, chiavi di accesso, biglietti della lotteria, posti numerati per concerti e partite sportive, ecc. Questo tipo speciale di token ha possibilità incredibili, quindi merita uno standard adeguato, e l'ERC-721 è nato per risolvere questo problema!
Cos'è l'ERC-721?
L'ERC-721 introduce uno standard per gli NFT; in altre parole, questo tipo di token è unico e può avere un valore diverso rispetto a un altro token proveniente dallo stesso contratto intelligente, magari a causa della sua età, rarità o persino di qualcos'altro come il suo aspetto visivo. Aspetta, aspetto visivo?
Sì! Tutti gli NFT hanno una variabile uint256 chiamata tokenId, quindi per qualsiasi contratto ERC-721, la coppia indirizzo del contratto, uint256 tokenId deve essere globalmente unica. Detto questo, una dApp può avere un "convertitore" che utilizza il tokenId come input e restituisce un'immagine di qualcosa di fantastico, come zombi, armi, abilità o gattini incredibili!
Prerequisiti
Corpo
L'ERC-721 (Ethereum Request for Comments 721), proposto da William Entriken, Dieter Shirley, Jacob Evans e Nastassia Sachs nel gennaio 2018, è uno standard per token non fungibili che implementa un'API per i token all'interno dei contratti intelligenti.
Fornisce funzionalità come il trasferimento di token da un account a un altro, l'ottenimento del saldo attuale dei token di un account, l'identificazione del proprietario di un token specifico e anche l'offerta totale del token disponibile sulla rete. Oltre a queste, ha anche altre funzionalità, come l'approvazione affinché una quantità di token da un account possa essere spostata da un account di terze parti.
Se un contratto intelligente implementa i seguenti metodi ed eventi, può essere definito un contratto di token non fungibili ERC-721 e, una volta distribuito, sarà responsabile di tenere traccia dei token creati su Ethereum.
Da EIP-721 (opens in a new tab):
Metodi
1 function balanceOf(address _owner) external view returns (uint256);2 function ownerOf(uint256 _tokenId) external view returns (address);3 function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;4 function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;5 function transferFrom(address _from, address _to, uint256 _tokenId) external payable;6 function approve(address _approved, uint256 _tokenId) external payable;7 function setApprovalForAll(address _operator, bool _approved) external;8 function getApproved(uint256 _tokenId) external view returns (address);9 function isApprovedForAll(address _owner, address _operator) external view returns (bool);Mostra tuttoEventi
1 event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);2 event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);3 event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);Esempi
Vediamo come uno standard sia così importante per semplificarci l'ispezione di qualsiasi contratto di token ERC-721 su Ethereum. Abbiamo solo bisogno dell'Application Binary Interface (ABI) del contratto per creare un'interfaccia verso qualsiasi token ERC-721. Come puoi vedere di seguito, utilizzeremo un'ABI semplificata, per renderlo un esempio a basso attrito.
Esempio con Web3.py
Innanzitutto, assicurati di aver installato la libreria Python Web3.py (opens in a new tab):
1pip install web31from web3 import Web32from web3._utils.events import get_event_data345w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))67ck_token_addr = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" # Contratto CryptoKitties89acc_address = "0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C" # Asta di vendita CryptoKitties1011# Questa è una Contract Application Binary Interface (ABI) semplificata di un contratto NFT ERC-721.12# Esporrà solo i metodi: balanceOf(address), name(), ownerOf(tokenId), symbol(), totalSupply()13simplified_abi = [14 {15 'inputs': [{'internalType': 'address', 'name': 'owner', 'type': 'address'}],16 'name': 'balanceOf',17 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],18 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True19 },20 {21 'inputs': [],22 'name': 'name',23 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],24 'stateMutability': 'view', 'type': 'function', 'constant': True25 },26 {27 'inputs': [{'internalType': 'uint256', 'name': 'tokenId', 'type': 'uint256'}],28 'name': 'ownerOf',29 'outputs': [{'internalType': 'address', 'name': '', 'type': 'address'}],30 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True31 },32 {33 'inputs': [],34 'name': 'symbol',35 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],36 'stateMutability': 'view', 'type': 'function', 'constant': True37 },38 {39 'inputs': [],40 'name': 'totalSupply',41 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],42 'stateMutability': 'view', 'type': 'function', 'constant': True43 },44]4546ck_extra_abi = [47 {48 'inputs': [],49 'name': 'pregnantKitties',50 'outputs': [{'name': '', 'type': 'uint256'}],51 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True52 },53 {54 'inputs': [{'name': '_kittyId', 'type': 'uint256'}],55 'name': 'isPregnant',56 'outputs': [{'name': '', 'type': 'bool'}],57 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True58 }59]6061ck_contract = w3.eth.contract(address=w3.to_checksum_address(ck_token_addr), abi=simplified_abi+ck_extra_abi)62name = ck_contract.functions.name().call()63symbol = ck_contract.functions.symbol().call()64kitties_auctions = ck_contract.functions.balanceOf(acc_address).call()65print(f"{name} [{symbol}] NFTs in Auctions: {kitties_auctions}")6667pregnant_kitties = ck_contract.functions.pregnantKitties().call()68print(f"{name} [{symbol}] NFTs Pregnants: {pregnant_kitties}")6970# Utilizzo dell'ABI dell'evento Transfer per ottenere informazioni sui Kitties trasferiti.71tx_event_abi = {72 'anonymous': False,73 'inputs': [74 {'indexed': False, 'name': 'from', 'type': 'address'},75 {'indexed': False, 'name': 'to', 'type': 'address'},76 {'indexed': False, 'name': 'tokenId', 'type': 'uint256'}],77 'name': 'Transfer',78 'type': 'event'79}8081# Abbiamo bisogno della firma dell'evento per filtrare i log82event_signature = w3.keccak(text="Transfer(address,address,uint256)").hex()8384logs = w3.eth.get_logs({85 "fromBlock": w3.eth.block_number - 120,86 "address": w3.to_checksum_address(ck_token_addr),87 "topics": [event_signature]88})8990# Note:91# - Aumenta il numero di blocchi oltre 120 se non viene restituito alcun evento Transfer.92# - Se non hai trovato alcun evento Transfer, puoi anche provare a ottenere un tokenId su:93# https://etherscan.io/address/0x06012c8cf97BEaD5deAe237070F9587f8E7A266d#events94# Fai clic per espandere i log dell'evento e copia il suo argomento "tokenId"95recent_tx = [get_event_data(w3.codec, tx_event_abi, log)["args"] for log in logs]9697if recent_tx:98 kitty_id = recent_tx[0]['tokenId'] # Incolla qui il "tokenId" dal link sopra99 is_pregnant = ck_contract.functions.isPregnant(kitty_id).call()100 print(f"{name} [{symbol}] NFTs {kitty_id} is pregnant: {is_pregnant}")Mostra tuttoIl contratto di CryptoKitties ha alcuni eventi interessanti oltre a quelli standard.
Controlliamone due: Pregnant e Birth.
1# Utilizzo dell'ABI degli eventi Pregnant e Birth per ottenere informazioni sui nuovi Kitties.2ck_extra_events_abi = [3 {4 'anonymous': False,5 'inputs': [6 {'indexed': False, 'name': 'owner', 'type': 'address'},7 {'indexed': False, 'name': 'matronId', 'type': 'uint256'},8 {'indexed': False, 'name': 'sireId', 'type': 'uint256'},9 {'indexed': False, 'name': 'cooldownEndBlock', 'type': 'uint256'}],10 'name': 'Pregnant',11 'type': 'event'12 },13 {14 'anonymous': False,15 'inputs': [16 {'indexed': False, 'name': 'owner', 'type': 'address'},17 {'indexed': False, 'name': 'kittyId', 'type': 'uint256'},18 {'indexed': False, 'name': 'matronId', 'type': 'uint256'},19 {'indexed': False, 'name': 'sireId', 'type': 'uint256'},20 {'indexed': False, 'name': 'genes', 'type': 'uint256'}],21 'name': 'Birth',22 'type': 'event'23 }]2425# Abbiamo bisogno della firma dell'evento per filtrare i log26ck_event_signatures = [27 w3.keccak(text="Pregnant(address,uint256,uint256,uint256)").hex(),28 w3.keccak(text="Birth(address,uint256,uint256,uint256,uint256)").hex(),29]3031# Ecco un evento Pregnant:32# - https://etherscan.io/tx/0xc97eb514a41004acc447ac9d0d6a27ea6da305ac8b877dff37e49db42e1f8cef#eventlog33pregnant_logs = w3.eth.get_logs({34 "fromBlock": w3.eth.block_number - 120,35 "address": w3.to_checksum_address(ck_token_addr),36 "topics": [ck_event_signatures[0]]37})3839recent_pregnants = [get_event_data(w3.codec, ck_extra_events_abi[0], log)["args"] for log in pregnant_logs]4041# Ecco un evento Birth:42# - https://etherscan.io/tx/0x3978028e08a25bb4c44f7877eb3573b9644309c044bf087e335397f16356340a43birth_logs = w3.eth.get_logs({44 "fromBlock": w3.eth.block_number - 120,45 "address": w3.to_checksum_address(ck_token_addr),46 "topics": [ck_event_signatures[1]]47})4849recent_births = [get_event_data(w3.codec, ck_extra_events_abi[1], log)["args"] for log in birth_logs]Mostra tuttoNFT popolari
- Etherscan NFT Tracker (opens in a new tab) elenca i migliori NFT su Ethereum per volume di trasferimenti.
- CryptoKitties (opens in a new tab) è un gioco incentrato su creature allevabili, collezionabili e adorabili che chiamiamo CryptoKitties.
- Sorare (opens in a new tab) è un gioco di fantacalcio globale in cui puoi raccogliere oggetti da collezione in edizione limitata, gestire le tue squadre e competere per vincere premi.
- L'Ethereum Name Service (ENS) (opens in a new tab) offre un modo sicuro e decentralizzato per indirizzare le risorse sia sulla blockchain che fuori utilizzando nomi semplici e leggibili dall'uomo.
- POAP (opens in a new tab) distribuisce NFT gratuiti alle persone che partecipano a eventi o completano azioni specifiche. I POAP sono gratuiti da creare e distribuire.
- Unstoppable Domains (opens in a new tab) è un'azienda con sede a San Francisco che crea domini sulle blockchain. I domini blockchain sostituiscono gli indirizzi di criptovaluta con nomi leggibili dall'uomo e possono essere utilizzati per abilitare siti web resistenti alla censura.
- Gods Unchained Cards (opens in a new tab) è un gioco di carte collezionabili (TCG) sulla blockchain di Ethereum che utilizza gli NFT per conferire la vera proprietà alle risorse di gioco.
- Bored Ape Yacht Club (opens in a new tab) è una collezione di 10.000 NFT unici che, oltre a essere un'opera d'arte di comprovata rarità, funge da token di appartenenza al club, fornendo vantaggi e benefici ai membri che aumentano nel tempo grazie agli sforzi della community.
Letture consigliate
- EIP-721: Standard dei token non fungibili ERC-721 (opens in a new tab)
- OpenZeppelin - Documentazione ERC-721 (opens in a new tab)
- OpenZeppelin - Implementazione ERC-721 (opens in a new tab)
- API per NFT di Alchemy (opens in a new tab)
Tutorial: Sviluppare con i token non fungibili (ERC-721) su Ethereum
- Guida al contratto ERC-721 in Vyper – Una guida annotata di un contratto NFT ERC-721 completo scritto in Vyper.
- Come scrivere e distribuire un NFT (Parte 1/3) – Guida passo passo per scrivere e distribuire il tuo primo contratto intelligente ERC-721.
- Come coniare un NFT (Parte 2/3) – Come coniare un NFT ERC-721 utilizzando il tuo contratto intelligente distribuito e Web3.
- Come visualizzare il tuo NFT nel tuo portafoglio (Parte 3/3) – Come visualizzare il tuo NFT coniato in MetaMask dopo la distribuzione.
- Tutorial per coniare NFT – Crea una dApp full-stack per coniare NFT con un frontend React, MetaMask e Alchemy.