Gli standard sono importanti per le organizzazioni, il mondo industriale e finanziario, il commercio. Pensiamo a come, dopo la seconda guerra mondiale, l’adozione di un modulo standard per il trasporto merci, il container, abbia favorito l’esplosione del commercio globale. O come i grafici più comuni, come quelli a torta o gli istogrammi, siano usati abitualmente come una sorta di lingua franca internazionale e inter-settoriale.
La standardizzazione può essere un processo deliberato. Regole, formati, linguaggi sono individuati, concordati e fissati grazie a organizzazioni come l’ISO (International Organization for Standardization) o il W3C (World Wide Web Consortium) dopo accurate fasi di analisi e valutazione.
Ma può anche essere un processo “de facto”, in cui pratiche e strumenti divengono d’uso comune in maniera informale, grazie a un’adozione spontanea e diffusa dovuta a molteplici fattori, anche casuali (Knowledge work standardization, 2021). L’adozione negli anni ’80 dello standard VHS per le videocassette può essere citata come esempio.
Nel mondo dell’informatica, fin dall’inizio, gli standard emergono spesso all’interno delle varie comunità di sviluppatori ed esperti. Il mondo del software libero si avvale di forum e chat in cui avvengono discussioni, spesso infuocate, preludio a votazioni e approvazioni su standard e specifiche.
La comunità raccoltasi intorno al progetto Ethereum non si sottrae a questo processo decentralizzato e partecipativo.
Le proposte per nuove funzionalità passano attraverso le Ethereum Improvement Proposals (EIPs), documenti tecnici su cui la community discute attraverso un processo standardizzato. Se approvate, le modifiche diventano operative. Nel caso di nuovi standard per i token, queste prendono il nome di ERC (Ethereum Request for Comments). (Introduction to Ethereum Improvement Proposals (EIPs), 2021).
Gli ERC sono smart contract, cioè parti di codice, scritte in Solidity, un linguaggio simile al JavaScript.
Nella definizione di un ERC il codice definisce quelle che in gergo informatico si chiamano interfacce; sono funzioni minimali che indicano COSA fanno ma non COME. Possiedono delle variabili di ingresso e definiscono quale output producono. Tutto qui. L’implementazione di queste funzioni è libera, ma per rispettare lo standard di un particolare ERC lo smart contract deve contenere tutte le funzioni previste.[1] Sono previsti inoltre degli “eventi” legati ad alcune funzioni: questi eventi vengono memorizzati nella blockchain.
Uno standard ERC così definito – come l’ERC-20 o l’ERC-721 di cui parleremo tra poco – permette l’integrazione con altri smart contracts e token, con wallets e con le piattaforme per il marketplace.
1.1. ERC-20
L’ERC-20 è stato creato nel 2015 da Fabian Vogelsteller e Vitalik Buterin e riconosciuto ufficialmente nel 2017 (verificare). Lo scopo è quello di definire uno standard per i token fungibili, cioè identici tra loro per scopo e valore.
È importante che gli sviluppatori non debbano partire da zero ogni volta che viene creato un nuovo token o una dApp.
L’ERC-20 permette di creare proprie cripto-valute basate su Ethereum ma anche gettoni per raccolte punti, crowdfunding, sistemi di reputazione nelle piattaforme online, azioni oltre che rappresentazioni digitali di oggetti fisici fungibili.
È importante che gli sviluppatori non debbano partire da zero ogni volta che viene creato un nuovo token o una dApp. La presenza di uno standard condiviso crea un effetto rete, grazie all’interoperabilità del proprio token con centinaia di altri e con wallet e marketplace.
Grazie all’ERC-20 sono stati creati:
- Utility tokens, che possono essere usati per ottenere un determinato servizi.
- Security tokens, simili ad azioni od obbligazioni.
- Stablecoins, cioè criptovalute relativamente stabili perché ancorate a un asset esterno, come una valuta o un metallo prezioso.
Agli esordi lo standard è stato utilizzato per le famigerate ICO, simili alle offerte pubbliche di acquisto ma realizzate tramite token/azioni “ad hoc” creati e venduti dalle startup per finanziarsi. Ma nel tempo questa tipologia di token è stata utilizzata per scopi sempre più sofisticati, diversi dei quali in ambito DeFi (Decentralized Finance).
A dicembre 2020 sono censiti più di 800 progetti basati su ERC-20 e più di 350.000 token contracts (Hertig, 2021). Tra i token più famosi e con capitalizzazione più alta vi sono lo stablecoin Tether, BNB, ChainLink e UniSwap.
Vi sono sei funzioni e due eventi che definiscono lo standard (Vogelsteller Fabian, 2015).
function totalSupply():restituisce come valore il numero totale di token (di un particolare tipo, per esempio di tether)
function balanceOf(address account): restituisce come valore il numero totale di token posseduti dall’indirizzo (utente) “account”
function transfer(address recipient, uint256 amount):trasferisce un certo numero di token (“amount”) dall’indirizzo dell’utente che chiama questa funzione all’indirizzo (utente) “recipient”. Restituisce un valore booleano (vero/falso) che indica se l’operazione ha avuto successo o no. La funzione fa scattare l’evento “Transfer”
function allowance(address owner, address spender): la funzione dà il permesso all’indirizzo (utente) “spender” di spendere i token dell’indirizzo (utente) “owner” Restituisce un valore booleano (vero/falso) che indica se l’operazione ha avuto successo o no. La funzione fa scattare l’evento “Approval”
function transferFrom(address sender, address recipient, uint256 amount): trasferisce un certo numero (“amount”) di token dall’indirizzo (utente) “sender” a quello “recipient”. Restituisce un valore booleano (vero/falso) che indica se l’operazione ha avuto successo o no. La funzione fa scattare l’evento “Transfer”
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
Altre tre funzioni sono opzionali e costituiscono dei metadati del token: quella che restituisce il nome al token (come “THETER”, il simbolo (“USDT”) e il numero di cifre decimali usate.
È importante sottolineare che le funzioni “obbligatorie” possono essere affiancate da altre funzioni nello smart contract che definisce uno specifico token.
Una domanda che ci si può fare è: posso convertire un token ERC-20 in valuta corrente tipo euro? La risposta è: dipende. Per convertire un token occorre rivolgersi alle piattaforme che operano come (cripto)cambiavalute. Ognuna di esse supporta diversi token ERC-20 e ne effettua il cambio direttamente in valuta corrente o in ether. Per essere supportati, i token devono essere parte di un progetto o di una startup che abbia dimostrato, in un ragionevole lasso di tempo, serietà e solidità.
1.2. ERC-721
Come abbiamo visto, lo standard ERC-20 crea token fungibili quindi intercambiabili. Nel 2017 la software company LarvaLabs ha creato un progetto di cripto-arte. Si tratta di piccoli personaggi di pochi pixel. Ognuno diverso dall’altro, hanno un “certificato di proprietà” memorizzato sotto forma di token su Ethereum.
Il problema che si pose fu quello di ampliare il contratto standard ERC-20 per rendere conto della natura unica di ogni immagine: sono beni non fungibili, il cui valore è indipendente l’uno dall’altro.
Lo smart contract ideato dai LarvaLabs divenne la base per lo standard ERC-721 che permette di realizzare token non fungibili.
Nel settembre del 2017 Dieter Shirley presentò la proposta EIP721. Nel dicembre di quell’anno esplose la mania dei CryptoKitties, gattini digitali collezionabili (e rivendibili) grazie all’utilizzo di uno smart contract basato su quella proposta, ancora non uno standard. Lo divenne nel gennaio del 2018 con il nome di ERC-721 a firma di William Entriken, Dieter Shirley, Jacob Evans, Nastassia Sachs. I token di questo tipo sono detti NFT (Non-Fungible Token) o anche “deeds” (certificati di proprietà).
Nel documento che definisce lo standard, gli autori ipotizzano tre “universi” di asset che possono beneficiarne (aggiungendo che “sappiamo che ne sognerete molti altri”) (Entriken W., 2018).
– Asset fisici, come quadri, case.
– Oggetti da collezione virtuali, come i CriptoKitties o figurine collezionabili (come quelle dei calciatori).
– Asset di “valore negativo”: prestiti, oneri e simili.
Ogni NFT è identificato da un ID definito nello smart contract che lo implementa: non ci possono essere due ID uguali generati dallo stesso contratto. Quindi la coppia (contract address, ID) identifica univocamente il token.
Lo smart contract può essere creato attraverso l’operazione di “minting” o distrutto (“bruciato”) attraverso il “burning”. Lo standard non si occupa di definire queste operazioni che restano responsabilità degli sviluppatori. Ogni smart contract ERC-721 può gestire un numero virtualmente illimitato di token (almeno 2128).
I metadata associabili al token, come nome e simbolo dell’NFT, sono opzionali. Non sono univoci, e possono esserci due smart contract che usano lo stesso nome e lo stesso simbolo per il loro NFT. È un punto su cui fare attenzione, visto che possono esserci, ad esempio, due artefatti digitali associati a un NFT con lo stesso nome (ma gestiti da smart contract differenti).
Una caratteristica fondante dello standard ERC-721 è la possibilità, da parte del possessore di un NFT, di delegarne la compravendita a una terza parte, un “operatore” come un broker, un wallet o un “banditore d’asta”.
Vediamo quali sono le funzioni obbligatorie per lo standard.
function balanceOf(address _owner) external view returns (uint256): restituisce il numero di NFT posseduti da un proprietario (“_owner”). Si parla di NFT gestiti dallo smart contract in questione, di quel particolare tipo, non in generale di tutti gli NFT posseduti da quell’indirizzo. Per analogia, è come contare il numero di opere comprate da un collezionista da una data galleria, non tutte quelle che possiede.
function ownerOf(uint256 _tokenId) external view returns (address): restituisce l’indirizzo roprietario di uno specifico NFT. Anche qui, ci si riferisce al token gestito da un particolare smart contract ERC-721. Seguendo l’analogia precedente, si risale al proprietario dell’opera avente numero di catalogo xyz comprata in una determinata galleria.
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable: trasferisce la proprietà dell’ NFT con ID “_tokenId” dall’indirizzo/utente “_from” all’indirizzo/utente “_to” Tramite il parametro “data” possono essere inviati dati all’indirizzo del ricevente. La funzione deve segnalare errori quali il fatto che “_from” non è l’attuale proprietario dell’NFT, che “_to” è l’indirizzo 0000 (non valido), che _tokenID non è un NFT valido.
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable: uguale alla precedente, senza il parametro “data”.
function transferFrom(address _from, address _to, uint256 _tokenId) external payable: simile alla precedente, ma con la necessità, da parte di chi invoca la funzione, di confermare che “_to” sia un indirizzo idoneo per ricevere l’NFT, pena la perdita definitiva del token.
function approve(address _approved, uint256 _tokenId) external payable: modifica o conferma l’attuale indirizzo/controllore dell’NFT (proprietario o operatore).
function setApprovalForAll(address _operator, bool _approved) external: l’operatore “_operator” è autorizzato a gestire tutti gli NFT (coniati da un certo smart contract) di chi invoca la funzione.
function getApproved(uint256 _tokenId) external view returns (address): restituisce l’indirizzo che gestisce attualmente l’NFT.
function isApprovedForAll(address _owner, address _operator) external view returns (bool): conferma o meno se “_operator” è autorizzato a gestire gli NFT di “_owner”.
Anche in questo standard esistono tre eventi.
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId): evento emesso quando cambia la proprietà di un NFT. Se _”from” è 0, l’NFT è coniato, se “_to” è zero l’NFT è distrutto (bruciato).
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId): evento emesso quando un indirizzo approvato per un NFT è cambiato, riaffermato o resettato a “nessuno”.
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved): emesso quando un operatore è abilitato o disabilitato a gestire tutti gli NFT dell’ “_owner”.
Una funzione è dedicata all’operatore “terzo” (il wallet, il broker, il marketplace) che accetta le funzioni di trasferimento “sicure”.
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4): restitusce una conferma dell’avvenuta transazione.
Opzionali sono le funzioni che definiscono i metadati: oltre al nome e al simbolo della collezione di NFT gestita dal contratto, vi è la funzione tokenURI (uint256 _tokenId) che restituisce l’URI (l’indirizzo ovvero l’URL) dell’oggetto digitale (per esempio un’immagine) gestito dall’NFT. Problema tra uno e più nft
Infine, sempre opzionali, vi sono delle funzioni che restituiscono il numero di NFT gestiti dallo smart contract (esclusi quelli distrutti), l’indice dell’ultimo NFT (considerando la lista come un array) nell’intera collezione o in quella di un determinato proprietario.
Il punto più delicato, per le implicazioni che sottende, sono i metadati e in particolare il tokenURI che punta, direttamente o tramite un file JSON, a un indirizzo dove è fisicamente memorizzato l’asset. È chiaro che esiste un problema: per varie ragioni l’URL può essere modificato senza che il metadato venga aggiornato[2] oppure l’asset può venire cancellato da quell’indirizzo. Ciò che rimane è un NFT senza più un asset associato, un po’come avere un certificato di proprietà di un quadro distrutto in un incendio. L’URL è spesso quello di un server o di una cloud proprietaria (del marketplace ad esempio): qual è il controllo che il proprietario dell’NFT ha sull’opera? Praticamente nullo, secondo alcuni pareri.
Perché, tranne eccezioni, gli asset non sono memorizzati nella blockchain?
Usare Ethereum come sistema di storage è costoso. Per memorizzare un kilobyte occorrono 640k gas, dove il “gas” è un’unità di misura legata al valore dell’ether (e usata anche come “percentuale” per ogni transazione effettuata): attualmente un kilobyte costa 120 euro circa (marzo 2021). Memorizzare un MB costerebbe quindi 120.000 euro!
Gli standard non sono eterni. Sono suscettibili di miglioramenti, aggiornamenti e sostituzioni. Gli ERC non fanno eccezione. È prevedibile una sorta di “evoluzione darwiniana” che crei protocolli più efficienti, differenziati e adeguati ai cambiamenti della blockchain di riferimento, in questo caso Ethereum.
Un esempio di questa evoluzione è l’ERC-1155 è nato nel 2018 su iniziativa di Witek Radomski, Andrew Cooke, Philippe Castonguay, James Therien, Eric Binet, Ronan Sandford (Radomski W., 2018). È uno standard multi-token che permette di implementare, nello stesso smart contract, token fungibili e classi differenti di token non fungibili. I metadata sono sempre esterni alla blockchain, memorizzati in un file JSON (Witek, 2019). Queste e altre caratteristiche rendono il protocollo più efficiente, in quanto consente il trasferimento di più token in un’unica transazione e la riduzione dei dati on-chain, risparmiando gas e alleggerendo il traffico su Ethereum.
[1] Solitamente non si ricrea ogni volta un’implementazione ex novo ma se ne usano alcune liberamente disponibili che costituiscono una sorta di standard de facto (per esempio quelle di Open Zeppelin o ConsenSys). Queste vengono poi modificate e personalizzate a seconda degli scopi del progetto di tokenizzazione.
[2] A chi tocca aggiornare il puntatore? Al creatore? All’attuale proprietario?
Riferimenti
Standard,” Ethereum Improvement Proposals, no. 721. Tratto il giorno 04 15, 2021 da eips.ethereum.org: https://eips.ethereum.org/EIPS/eip-721
Hertig, A. (2021, 03 23). What Is the ERC-20 Ethereum Token Standard? Tratto il giorno 04 11, 2021 da coindesk.com: https://www.coindesk.com/what-is-the-erc-20-ethereum-standard
Introduction to Ethereum Improvement Proposals (EIPs). (2021, 04 09). Tratto il giorno 04 09, 2021 da ethereum.org: https://ethereum.org/en/eips/
Knowledge work standardization. (2021). Tratto il giorno 04 08, 2021 da The Lab Consulting: https://thelabconsulting.com/standardization/
Radomski W., C. A. (2018). EIP-1155: ERC-1155 Multi Token Standard,” Ethereum Improvement Proposals, no. 1155. Tratto il giorno 04 28, 2021 da eips.ethereum.org: https://eips.ethereum.org/EIPS/eip-1155
Vogelsteller Fabian, B. V. (2015, 11 19). “EIP-20: ERC-20 Token Standard,” Ethereum Improvement Proposals, no. 20. Tratto il giorno 04 12, 2021 da eips.ethereum.org: https://eips.ethereum.org/EIPS/eip-20
Witek, R. (2019, 06 17). ERC-1155: The Final Token Standard on Ethereum. Tratto il giorno 05 28, 2021 da enjincoin.io: https://blog.enjincoin.io/erc-1155-the-final-token-standard-on-ethereum-a83fce9f5714
Rilasciato sotto licenza Creative Commons – CC BY-NC-ND
Attribuzione – Non Commerciale – Non Opere Derivate