Przejdź do głównej zawartości

Zrozumienie inteligentnego kontraktu tokenu ERC-20

smart kontrakty
tokeny
Solidity
erc-20
Początkujący
jdourlens
5 kwietnia 2020
4 minuta czytania

Jeden z najważniejszych standardów inteligentnych kontraktów na Ethereum znany jest jako ERC-20, który stał się standardem technicznym stosowanym w odniesieniu do wszystkich inteligentnych kontraktów w blockchainie Ethereum do implementacji zamiennych tokenów.

ERC-20 określa wspólną listę zasad, których powinny przestrzegać wszystkie zamienne tokeny Ethereum. W konsekwencji ten standard tokenów umożliwia deweloperom wszystkich typów dokładnie przewidzieć, jak nowe tokeny będą funkcjonować w ramach większego systemu Ethereum. Upraszcza to i ułatwia pracę deweloperom, ponieważ mogą oni kontynuować swoją pracę, wiedząc, że żaden nowy projekt nie będzie musiał być ponownie tworzony za każdym razem, gdy pojawi się nowy token, o ile będzie on zgodny z zasadami.

Oto, przedstawione w formie interfejsu, funkcje, które musi zaimplementować ERC-20. Jeśli nie jesteś pewien, czym jest interfejs, sprawdź nasz artykuł o programowaniu obiektowym w 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}
Pokaż wszystko

Oto szczegółowe wyjaśnienie przeznaczenia każdej funkcji. Następnie przedstawimy prostą implementację tokenu ERC-20.

Gettery

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

Zwraca liczbę istniejących tokenów. Ta funkcja jest getterem i nie modyfikuje stanu kontraktu. Pamiętaj, że w Solidity nie ma liczb zmiennoprzecinkowych. Dlatego większość tokenów przyjmuje 18 miejsc po przecinku i zwraca całkowitą podaż oraz inne wyniki jako 1000000000000000000 za 1 token. Nie każdy token ma 18 miejsc po przecinku i jest to coś, na co naprawdę trzeba uważać, mając do czynienia z tokenami.

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

Zwraca liczbę tokenów posiadanych przez dany adres (account). Ta funkcja jest getterem i nie modyfikuje stanu kontraktu.

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

Standard ERC-20 umożliwia jednemu adresowi przyznanie innemu adresowi zezwolenia na pobranie z niego tokenów. Ten getter zwraca pozostałą liczbę tokenów, które spender będzie mógł wydać w imieniu owner. Ta funkcja jest getterem, nie modyfikuje stanu kontraktu i domyślnie powinna zwracać 0.

Funkcje

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

Przenosi amount tokenów z adresu wywołującego funkcję (msg.sender) na adres odbiorcy. Ta funkcja emituje zdefiniowane później zdarzenie Transfer. Zwraca true, jeśli transfer był możliwy.

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

Ustawia allowance – kwotę, którą spender może przelać z salda wywołującego funkcję (msg.sender). Ta funkcja emituje zdarzenie Approval. Funkcja zwraca informację, czy allowance zostało pomyślnie ustawione.

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

Przenosi amount tokenów z adresu sender na adres recipient za pomocą mechanizmu allowance. Kwota amount jest następnie odejmowana od allowance osoby wywołującej. Ta funkcja emituje zdarzenie Transfer.

Zdarzenia

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

To zdarzenie jest emitowane, gdy liczba tokenów (value) jest wysyłana z adresu from na adres to.

W przypadku wybijania nowych tokenów transfer jest zazwyczaj from adresu 0x00..0000, natomiast w przypadku spalania tokenów transfer jest to adresu 0x00..0000.

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

To zdarzenie jest emitowane, gdy kwota tokenów (value) jest zatwierdzana przez owner do użycia przez spender.

Podstawowa implementacja tokenów ERC-20

Oto najprostszy kod, na którym można oprzeć swój 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}
Pokaż wszystko

Inną doskonałą implementacją standardu tokenów ERC-20 jest implementacja ERC-20 od OpenZeppelin (opens in a new tab).

Strona ostatnio zaktualizowana: 21 sierpnia 2025

Czy ten samouczek był pomocny?