Salt la conținutul principal

Înțelegerea contractului inteligent de token ERC-20

contracte inteligentetokenurisoliditynoțiuni de bazăerc-20
Începător
jdourlens
EthereumDev(opens in a new tab)
5 aprilie 2020
5 minute de citit minute read
comp-tutorial-metadata-tip-author 0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE

Unul dintre cele mai importante standarde ale contractelor inteligente de pe Ethereum este cunoscut sub numele de ERC-20; a apărut ca standard tehnic utilizat pentru toate contractele inteligente de pe blockchain-ul Ethereum pentru implementarea tokenurilor fungibile.

ERC-20 definește o listă comună de reguli la care trebuie să adere toate tokenurile fungibile Ethereum. În consecință, acest token standard le permite programatorilor de toate tipurile să estimeze cu precizie modul în care vor funcţiona noile tokenuri în cadrul unui sistem Ethereum mai mare. Acest lucru simplifică și facilitează sarcinile programatorilor, deoarece îşi pot continua lucrările știind că fiecare proiect nou nu va trebui să fie refăcut de fiecare dată când este lansat un nou token, atâta timp cât tokenul urmează regulile.

Iată funcțiile pe care trebuie să leimplementeze ERC-20, prezentate ca interfaţă. Dacă nu știţi sigur ce este o interfață: citiţi articolul nostru despre programarea OOP în 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}
Afișează tot
Copiați

Iată un explicator linie cu linie a utilităţii fiecărei funcții. După aceasta vom prezenta o implementare simplă a unui token ERC-20.

Getters

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

Răspunde prin numărul de tokenuri existente. Această funcție este un „getter” și nu modifică starea contractului. Rețineţi că nu există virgule mobile în Solidity. Prin urmare, cele mai multe tokenuri adoptă 18 zecimale și vor răspunde prin totalul disponibil și alte rezultate după cum urmează 1000000000000000000 pentru 1 token. Nu toate tokenurile au 18 zecimale și acesta este un lucru căruia să-i acordaţi atenţie când aveţi de-a face cu tokenurile.

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

Răspunde prin numărul de tokenuri deținute de o adresă (account). Această funcție este un „getter” și nu modifică starea contractului.

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

Standardul ERC-20 permite unei adrese să ofere unei alte adrese o alocaţie pentru a putea recupera tokenuri de la aceasra. Această funcție „getter” returnează numărul rămas de tokenuri pe care funcția spender va putea să le cheltuiască în numele proprietarului, funcția owner. Această funcție este un „getter” și nu modifică starea contractului și ar trebui să răspundă prin 0 în mod implicit.

Funcții

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

Mută numărul de token-uri amount de la adresa apelantului funcției (msg.sender) la adresa destinatarului. Această funcție emite evenimentul Transfer definit ulterior. Răspunde prin „true” dacă transferul a fost posibil.

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

Setează cât este suma alocată ce i se permite spenderului-să o transfere din soldul funcției „caller” (msg.sender). Această funcție emite evenimentul „Approval”. Funcția răspunde dacă „allowance” a fost setată cu succes.

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

Mută amount (numărul) de tokenuri de la expeditor la destinatar folosind mecanismul „allowance” (alocație). Apoi „amount” este dedus din „allowance” al apelantului. Această funcție emite evenimentul Transfer.

Evenimente

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

Acest eveniment este emis atunci când cantitatea de tokenuri (valori) este trimisă de la adresa from la adresa to.

În cazul emiterii de noi tokenuri, transferul este de obicei de la adresa from 0x00..0000, în timp ce în cazul arderii de tokenuri, transferul este trimis la adresa to 0x00..0000.

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

Acest eveniment este emis atunci când cantitatea de tokenuri (value) este aprobată de owner pentru a fi utilizate de către spender.

O implementare elementară a tokenurilor ERC-20

Iată cel mai simplu cod pe care să vă bazaţi tokenul ERC-20:

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}
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 event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
27 event Transfer(address indexed from, address indexed to, uint tokens);
28
29
30 mapping(address => uint256) balances;
31
32 mapping(address => mapping (address => uint256)) allowed;
33
34 uint256 totalSupply_;
35
36 using SafeMath for uint256;
37
38
39 constructor(uint256 total) public {
40 totalSupply_ = total;
41 balances[msg.sender] = totalSupply_;
42 }
43
44 function totalSupply() public override view returns (uint256) {
45 return totalSupply_;
46 }
47
48 function balanceOf(address tokenOwner) public override view returns (uint256) {
49 return balances[tokenOwner];
50 }
51
52 function transfer(address receiver, uint256 numTokens) public override returns (bool) {
53 require(numTokens <= balances[msg.sender]);
54 balances[msg.sender] = balances[msg.sender].sub(numTokens);
55 balances[receiver] = balances[receiver].add(numTokens);
56 emit Transfer(msg.sender, receiver, numTokens);
57 return true;
58 }
59
60 function approve(address delegate, uint256 numTokens) public override returns (bool) {
61 allowed[msg.sender][delegate] = numTokens;
62 emit Approval(msg.sender, delegate, numTokens);
63 return true;
64 }
65
66 function allowance(address owner, address delegate) public override view returns (uint) {
67 return allowed[owner][delegate];
68 }
69
70 function transferFrom(address owner, address buyer, uint256 numTokens) public override returns (bool) {
71 require(numTokens <= balances[owner]);
72 require(numTokens <= allowed[owner][msg.sender]);
73
74 balances[owner] = balances[owner].sub(numTokens);
75 allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens);
76 balances[buyer] = balances[buyer].add(numTokens);
77 emit Transfer(owner, buyer, numTokens);
78 return true;
79 }
80}
81
82library SafeMath {
83 function sub(uint256 a, uint256 b) internal pure returns (uint256) {
84 assert(b <= a);
85 return a - b;
86 }
87
88 function add(uint256 a, uint256 b) internal pure returns (uint256) {
89 uint256 c = a + b;
90 assert(c >= a);
91 return c;
92 }
93}
Afișează tot
Copiați

Această implementare utilizează biblioteca SafeMath. Citiţi tutorialul nostru dacă doriţi să afliaţi cum vă ajută biblioteca să acționaţi în caz de atac overflows și underflow în contractele dvs. inteligente(opens in a new tab).

O altă excelentă implementare a standardului de token ERC-20 este Implementarea OpenZeppelin-20(opens in a new tab).

Ultima modificare: @nicklcanada(opens in a new tab), 15 august 2023

A fost util acest tutorial?