Zrozumienie inteligentnego kontraktu tokenu ERC-20
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ólny wykaz 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 co do interfejsu: sprawdź nasz artykuł dotyczący Programowanie obiektowe w Solidity(opens in a new tab).
1pragma solidity ^0.6.0;23interface IERC20 {45 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);89 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);121314 event Transfer(address indexed from, address indexed to, uint256 value);15 event Approval(address indexed owner, address indexed spender, uint256 value);16}Pokaż wszystkoKopiuj
Oto szczegółowe wyjaśnienie przeznaczenia każdej funkcji. Następnie przedstawimy prostą implementację tokenu ERC-20.
Getters
1function totalSupply() external view returns (uint256);Kopiuj
Zwraca ilość istniejących tokenów. Ta funkcja jest to getter i nie modyfikuje stanu umowy. Pamiętaj, że w Solidity nie ma liczb zmiennoprzecinkowych. Dlatego większość tokenów przyjmuje 18 miejsc po przecinku i zwróci całkowitą podaż i inne wyniki w następujący sposób 100000000000000000000 dla 1 tokena. Nie każdy token ma 18 miejsc po przecinku i jest to coś, na co naprawdę musisz uważać, gdy masz do czynienia z tokenami.
1function balanceOf(address account) external view returns (uint256);Kopiuj
Zwraca ilość tokenów będących w posiadaniu adresu (account
). Ta funkcja jest to getter i nie modyfikuje stanu umowy.
1function allowance(address owner, address spender) external view returns (uint256);Kopiuj
Standard ERC-20 umożliwia adresowi przyznanie zezwolenia na inny adres, aby móc pobrać z niego tokeny. Ten getter zwraca pozostałą liczbę tokenów, które wydawca
będzie mógł wydać w imieniu właściciela
. Ta funkcja jest to getter i nie modyfikuje stanu umowy. Powinna domyślnie zwracać 0.
Funkcje
1function transfer(address recipient, uint256 amount) external returns (bool);Kopiuj
Przenosi amount
tokenów z adresu wywołującego funkcję (msg.sender
) na adres odbiorcy. Ta funkcja emituje zdarzenie Transfer
zdefiniowane później. Zwraca prawdę, jeśli transfer był możliwy.
1function approve(address spender, uint256 amount) external returns (bool);Kopiuj
Ustaw kwotę allowance
, jaką spender
może przenieść z salda wywołującego funkcję (msg.sender
). Ta funkcja emituje zdarzenie zatwierdzenia. Funkcja zwraca, czy dozwolony limit (allowance) został ustawiony.
1function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);Kopiuj
Przesyła amount
tokenów od sender
dto recipient
przy użyciu mechanizmu dozwolonego limitu. Wartość amount jest następnie odliczana od dozwolonego limitu wywołującego funkcję. Ta funkcja emituje zdarzenie Transfer
.
Zdarzenia
1event Transfer(address indexed from, address indexed to, uint256 value);Kopiuj
To zdarzenie jest emitowane, gdy ilość tokenów (wartość) jest wysyłana z adresu od
na adres do
.
W przypadku wybijania nowych tokenów transfer jest zazwyczaj from
adresu 0x00..0000, podczas gdy w przypadku wypalania tokenów transfer jest to
0x00..0000.
1event Approval(address indexed owner, address indexed spender, uint256 value);Kopiuj
To wydarzenie jest emitowane, gdy ilość tokenów (value
) jest zatwierdzona przez owner
do użycia przez spender
.
Podstawowa implementacja tokenów ERC-20
Oto najprostszy kod, z którego można oprzeć swój token ERC-20:
1pragma solidity ^0.6.0;23interface IERC20 {45 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);89 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);121314 event Transfer(address indexed from, address indexed to, uint256 value);15 event Approval(address indexed owner, address indexed spender, uint256 value);16}171819contract ERC20Basic is IERC20 {2021 string public constant name = "ERC20Basic";22 string public constant symbol = "ERC";23 uint8 public constant decimals = 18;242526 event Approval(address indexed tokenOwner, address indexed spender, uint tokens);27 event Transfer(address indexed from, address indexed to, uint tokens);282930 mapping(address => uint256) balances;3132 mapping(address => mapping (address => uint256)) allowed;3334 uint256 totalSupply_;3536 using SafeMath for uint256;373839 constructor(uint256 total) public {40 totalSupply_ = total;41 balances[msg.sender] = totalSupply_;42 }4344 function totalSupply() public override view returns (uint256) {45 return totalSupply_;46 }4748 function balanceOf(address tokenOwner) public override view returns (uint256) {49 return balances[tokenOwner];50 }5152 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 }5960 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 }6566 function allowance(address owner, address delegate) public override view returns (uint) {67 return allowed[owner][delegate];68 }6970 function transferFrom(address owner, address buyer, uint256 numTokens) public override returns (bool) {71 require(numTokens <= balances[owner]);72 require(numTokens <= allowed[owner][msg.sender]);7374 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}8182library SafeMath {83 function sub(uint256 a, uint256 b) internal pure returns (uint256) {84 assert(b <= a);85 return a - b;86 }8788 function add(uint256 a, uint256 b) internal pure returns (uint256) {89 uint256 c = a + b;90 assert(c >= a);91 return c;92 }93}Pokaż wszystkoKopiuj
Ta implementacja wykorzystuje bibliotekę SafeMath. Przeczytaj nasz samouczek, jeśli chcesz się dowiedzieć jak biblioteka pomaga Ci w obsłudze przepełnień i niedoborów w inteligentnych kontraktach(opens in a new tab).
Inną doskonałą implementacją standardu tokena ERC-20 jest implementacja OpenZeppelin ERC-20(opens in a new tab).
Ostatnia edycja: @nhsz(opens in a new tab), 15 sierpnia 2023