Vai al contenuto principale

Comprendere il contratto intelligente del token ERC-20

contratti intelligentitokenSolidityerc-20
Principiante
jdourlens
EthereumDev(opens in a new tab)
5 aprile 2020
4 minuti letti minute read
comp-tutorial-metadata-tip-author 0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE

Uno dei più importanti standard dei contratti intelligenti su Ethereum è noto come ERC-20; è emerso come lo standard tecnico usato per tutti i contratti intelligenti sulla blockchain di Ethereum per le implementazioni di token fungibili.

ERC-20 definisce una serie comune di regole che tutti i token fruibili di Ethereum devono seguire. Di conseguenza, consente a sviluppatori di ogni tipologia di prevedere con precisione come funzioneranno i nuovi token nell'ecosistema Ethereum. Questo semplifica lo sviluppo, in quanto si può lavorare con la sicurezza che ogni nuovo progetto non dovrà essere rifatto in seguito al rilascio di un nuovo token, se questo segue le regole.

Ecco qui di seguito, rappresentate da un'interfaccia, le funzioni che un token ERC-20 deve implementare. Se non sai cos'è un'interfaccia, leggi il nostro articolo sulla programmazione OOP in Solidity(opens in a new tab).

1pragma solidity ^0.6.0;
2
3interface IERC20 {
4
5 function totalSupply() external view returns (uint256);
6 function balanceOf(address account) external view returns (uint256);
7 function allowance(address owner, address spender) external view returns (uint256);
8
9 function transfer(address recipient, uint256 amount) external returns (bool);
10 function approve(address spender, uint256 amount) external returns (bool);
11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
12
13
14 event Transfer(address indexed from, address indexed to, uint256 value);
15 event Approval(address indexed owner, address indexed spender, uint256 value);
16}
Mostra tutto
Copia

Ecco una spiegazione riga per riga di ciascuna funzione. In seguito presenteremo una semplice implementazione di un token ERC-20.

Getter

1function totalSupply() external view returns (uint256);
Copia

Restituisce la quantità di token esistenti. Questa è una cosiddetta funzione getter e non altera lo stato del contratto. Tieni a mente che in Solidity non è prevista la virgola mobile. Perciò gran parte dei token adottano 18 decimali e restituiscono la disponibilità totale e altri risultati come 1000000000000000000 per 1 token. Non tutti i token hanno 18 decimali e questo è un aspetto a cui devi prestare molta attenzione quando interagisci con i token.

1function balanceOf(address account) external view returns (uint256);
Copia

Restituisce la quantità di token posseduti da un indirizzo (account). Questa è una funzione getter e non altera lo stato del contratto.

1function allowance(address owner, address spender) external view returns (uint256);
Copia

Lo standard ERC-20 consente ad un indirizzo di trasferire una somma a un altro indirizzo in modo da potervi recuperare token. Questa funzione getter restituisce il numero rimanente di token che lo spender potrà spendere per conto dell'owner. Questa funzione è un getter e non altera lo stato del contratto; per default dovrebbe restituire 0.

Funzioni

1function transfer(address recipient, uint256 amount) external returns (bool);
Copia

Sposta la quantità (amount) di token dall'indirizzo di chiama la funzione (msg.sender) a quello del destinatario. Questa funzione emette l'evento Transfer definito in seguito. Restituisce true se il trasferimento è stato effettuato.

1function approve(address spender, uint256 amount) external returns (bool);
Copia

Aggiorna l'importo di allowance che lo spender può trasferire dal saldo di chi chiama la funzione (msg.sender). Questa funzione emette l'evento Approval. La funzione restituisce un valore che indica se la somma è stata impostata.

1function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
Copia

Trasferisce l'importo (amount) di token da sender a recipient usando il meccanismo della disponibilità. L'importo viene poi sottratto dalla disponibilità del chiamante. Questa funzione emette l'evento Transfer.

Eventi

1event Transfer(address indexed from, address indexed to, uint256 value);
Copia

Questo evento viene emesso quando la quantità di token (value) è inviata dall'indirizzo from all'indirizzo to.

Nel caso del conio di nuovi token, il trasferimento è solitamente from l'indirizzo 0x00..0000, mentre nel caso in cui i token sono bruciati, il trasferimento è to 0x00..0000.

1event Approval(address indexed owner, address indexed spender, uint256 value);
Copia

Questo evento vien trasmesso ogni volta che la quantità di token (value) è approvata da owner per essere utilizzata da spender.

Implementazione di base dei token ERC-20

Ecco il codice più semplice su cui basare un token ERC-20:

1pragma solidity ^0.8.0;
2
3interface IERC20 {
4
5 function totalSupply() external view returns (uint256);
6 function balanceOf(address account) external view returns (uint256);
7 function allowance(address owner, address spender) external view returns (uint256);
8
9 function transfer(address recipient, uint256 amount) external returns (bool);
10 function approve(address spender, uint256 amount) external returns (bool);
11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
12
13
14 event Transfer(address indexed from, address indexed to, uint256 value);
15 event Approval(address indexed owner, address indexed spender, uint256 value);
16}
17
18
19contract ERC20Basic is IERC20 {
20
21 string public constant name = "ERC20Basic";
22 string public constant symbol = "ERC";
23 uint8 public constant decimals = 18;
24
25
26 mapping(address => uint256) balances;
27
28 mapping(address => mapping (address => uint256)) allowed;
29
30 uint256 totalSupply_ = 10 ether;
31
32
33 constructor() {
34 balances[msg.sender] = totalSupply_;
35 }
36
37 function totalSupply() public override view returns (uint256) {
38 return totalSupply_;
39 }
40
41 function balanceOf(address tokenOwner) public override view returns (uint256) {
42 return balances[tokenOwner];
43 }
44
45 function transfer(address receiver, uint256 numTokens) public override returns (bool) {
46 require(numTokens <= balances[msg.sender]);
47 balances[msg.sender] = balances[msg.sender]-numTokens;
48 balances[receiver] = balances[receiver]+numTokens;
49 emit Transfer(msg.sender, receiver, numTokens);
50 return true;
51 }
52
53 function approve(address delegate, uint256 numTokens) public override returns (bool) {
54 allowed[msg.sender][delegate] = numTokens;
55 emit Approval(msg.sender, delegate, numTokens);
56 return true;
57 }
58
59 function allowance(address owner, address delegate) public override view returns (uint) {
60 return allowed[owner][delegate];
61 }
62
63 function transferFrom(address owner, address buyer, uint256 numTokens) public override returns (bool) {
64 require(numTokens <= balances[owner]);
65 require(numTokens <= allowed[owner][msg.sender]);
66
67 balances[owner] = balances[owner]-numTokens;
68 allowed[owner][msg.sender] = allowed[owner][msg.sender]-numTokens;
69 balances[buyer] = balances[buyer]+numTokens;
70 emit Transfer(owner, buyer, numTokens);
71 return true;
72 }
73}
Mostra tutto
Copia

Un'altra eccellente implementazione dello standard token ERC-20 è l'implementazione ERC-20 OpenZeppelin(opens in a new tab).

Ultima modifica: @Herbie_23(opens in a new tab), 15 agosto 2023

Questo tutorial è stato utile?