Înțelegerea contractului inteligent de token ERC-20
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;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}Afișează totCopiaț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;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}Afișează totCopiaț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: @nhsz(opens in a new tab), 15 august 2023