Standard token non fungibile ERC-721
Ultima modifica: @ilrado(opens in a new tab), 19 novembre 2023
Introduzione
Cos'è un token non fungibile?
Un token non fungibile (NFT) è usato per identificare inequivocabilmente qualcosa o qualcuno. Questo tipo di Token è perfetto su piattaforme che offrono oggetti collezionabili, chiavi di accesso, biglietti della lotteria, posti numerati per concerti o eventi sportivi ecc. Questo particolare tipo di token offre possibilità straordinarie quindi si merita uno standard vero e proprio, ed ERC-721 serve proprio per questo!
Cos'è ERC-721?
L'ERC-721 introduce uno standard per gli NFT; in altre parole, questo tipo di Token è unico e può avere un valore differente da un altro Token dallo stesso Contratto Intelligente, forse a causa della sua età, rarità o persino ad altro, come il suo aspetto. Cosa? Aspetto?
Sì! Tutti gli NFT hanno una variabile uint256
chiamata tokenId
, quindi per i contratti ERC-721 la coppia contract address, uint256 tokenId
deve essere unica a livello globale. Detto ciò, una dapp può avere un "convertitore" che utilizza il tokenId
come input e restituisce l'immagine di qualcosa come zombie, armi, abilità o teneri gattini!
Prerequisiti
Corpo
L'ERC-721 (Ethereum Request for Comments 721), proposto da William Entriken, Dieter Shirely, Jacob Evans e Nastassia Sachs a gennaio 2018, è uno Standard del Token Non Fungibile che implementa un'API per i token nei Contratti Intelligenti.
Fornisce funzionalità come il trasferimento dei token da un conto all'altro, l'ottenimento del saldo corrente del token di un conto, l'ottenimento del proprietario di un token specifico, nonché l'offerta totale del token disponibile sulla rete. Oltre a ciò, ha alcune altre funzionalità, come approvare che un importo di token da un conto possa esser spostato da un conto di terze parti.
Se un Contratto Intelligente implementa i seguenti metodi ed eventi, può esser definito un Contratto a Token Non Fungibile 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 tuttoCopia
Eventi
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);Copia
Esempi
Vediamo perché uno standard è così importante per semplificare l'ispezione dei contratti token ERC-721 su Ethereum. Ci serve solo la Contract Application Binary Interface (ABI) per creare un'interfaccia per qualsiasi token ERC-721. Come puoi vedere di seguito, useremo un'ABI semplificata per fornire un esempio semplice da capire.
Esempio Web3.py
Prima di tutto, controlla di avere installato la libreria Python Web3.py(opens in a new tab):
1pip install web3
1from web3 import Web32from web3._utils.events import get_event_data345w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))67ck_token_addr = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" # CryptoKitties Contract89acc_address = "0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C" # CryptoKitties Sales Auction1011# This is a simplified Contract Application Binary Interface (ABI) of an ERC-721 NFT Contract.12# It will expose only the methods: 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# Using the Transfer Event ABI to get info about transferred Kitties.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# We need the event's signature to filter the logs82event_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# Notes:91# - Increase the number of blocks up from 120 if no Transfer event is returned.92# - If you didn't find any Transfer event you can also try to get a tokenId at:93# https://etherscan.io/address/0x06012c8cf97BEaD5deAe237070F9587f8E7A266d#events94# Click to expand the event's logs and copy its "tokenId" argument95recent_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'] # Paste the "tokenId" here from the link above99 is_pregnant = ck_contract.functions.isPregnant(kitty_id).call()100 print(f"{name} [{symbol}] NFTs {kitty_id} is pregnant: {is_pregnant}")Mostra tuttoCopia
Il contratto CryptoKitties contiene alcuni eventi interessanti oltre a quelli standard.
Diamo un'occhiata a due di questi, Pregnant
e Birth
.
1# Viene usata l'ABI Pregnant e Birth Events per ottenere informazioni sui nuovi gattini.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# We need the event's signature to filter the logs26ck_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# Here is a Pregnant Event: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# Here is a Birth Event: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 tuttoCopia
NFT più popolari
- Etherscan NFT Tracker(opens in a new tab) elenca i principali NFT su Ethereum per volume di trasferimento.
- CryptoKitties(opens in a new tab) è un gioco basato su creature a cui si può dare da mangiare, collezionabili e molto tenere chiamate CryptoKitties.
- Sorare(opens in a new tab) è un gioco di calcio fantasy globale in cui si possono collezionare oggetti in edizione limitata e gestire squadre, gareggiando per vincere premi.
- The Ethereum Name Service (ENS)(opens in a new tab) offre un modo sicuro e decentralizzato per indirizzare risorse sia all'interno che all'esterno della blockchain utilizzando nomi semplici e leggibili.
- POAP(opens in a new tab) offre NFT gratuiti alle persone che partecipano a eventi o completano azioni specifiche. I POAP sono creabili e distribuibili gratuitamente.
- Unstoppable Domains(opens in a new tab) è un'azienda di San Francisco che crea domini sulle blockchain. I domini delle blockchain sostituiscono gli indirizzi della criptovaluta con nomi leggibili dall'uomo, che possono essere usati per creare siti web resistenti alla censura.
- Gods Unchained Cards(opens in a new tab) è un gioco di carte collezionabili sulla blockchain Ethereum che usa gli NFT per dare una proprietà reale alle risorse del gioco.
- Bored Ape Yacht Club(opens in a new tab) è una raccolta di 10.000 NFT unici che, oltre a essere opere d'arte la cui rarità è dimostrata, fungono da token di appartenenza al club, fornendo ai membri vantaggi e benefici che possono aumentare nel tempo come risultato degli sforzi della community.