Înțelegerea contractului inteligent ERC-20
Unul dintre cele mai importante standarde de contract inteligent 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ă prezică cu precizie modul în care noile tokenuri vor funcționa în cadrul unui sistem Ethereum mai mare. Acest lucru simplifică și ușurează sarcinile programatorilor, deoarece pot lucra în continuare ș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.
Aici, sunt prezentate ca o interfață, funcțiile pe care trebuie să leimplementeze ERC-20. Dacă nu știi sigur ce este o interfață: citește articolul nostru despre programarea OOP în Solidity.
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}17Afișează totCopiere
Iată un explicator linie cu linie a fiecărei funcții. După aceasta vom prezenta o implementare simplă a unui token ERC-20.
Getters
1function totalSupply() external view returns (uint256);2Copiere
Returnează numărul de tokenuri existente. Această funcție este un „getter” și nu modifică starea contractului. Reține că nu există virgule mobile în Solidity. Prin urmare, cele mai multe tokenuri adoptă 18 zecimale și vor returna totalul de aprovizionare și alte rezultate după cum urmează 1000000000000000000 pentru 1 token. Nu toate tokenurile au 18 zecimale și acesta este un lucru pe care trebuie să-l urmărești atunci când ai de-a face cu tokenuri.
1function balanceOf(address account) external view returns (uint256);2Copiere
Returnează 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);2Copiere
Standardul ERC-20 permite unei adrese să ofere unei alte adrese limita de tokenuri pe care ultima poate să le obțină de la prima. Această funcție „getter” returnează numărul rămas de tokenuri pe care funcția spender
va putea să o cheltuiască în numele proprietarului, funcția owner
. Această funcție este un „getter” și nu modifică starea contractului și ar trebui să întoarcă 0 în mod implicit.
Funcții
1function transfer(address recipient, uint256 amount) external returns (bool);2Copiere
Mută numărul de tokenuri amount
de la adresa apelantului funcției (msg.sender
) la adresa destinatarului. Această funcție emite evenimentul Transfer
definit mai târziu. Returnează „true” dacă transferul a fost posibil.
1function approve(address spender, uint256 amount) external returns (bool);2Copiere
Setează cantitatea de allowance
care este permisă spender
-lui să o transfere din soldul funcției „caller” (msg.sender
). Această funcție emite evenimentul „Approval”. Funcția returnează dacă „allowance” a fost setată cu succes.
1function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);2Copiere
Mută amount
(numărul) de tokenuri de la sender
la recipient
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);2Copiere
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 distrugerii de tokenuri, transferul este trimis la adresa to
0x00..0000.
1event Approval(address indexed owner, address indexed spender, uint256 value);2Copiere
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 de bază a tokenurilor ERC-20
Aici este cel mai simplu cod pe care să-ți bazezi tokenul tău 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}94Afișează totCopiere
Această implementare utilizează biblioteca SafeMath. Citește tutorialul nostru dacă dorești să afli cum te ajută biblioteca să acționezi în caz de atac overflows și underflow în contractele tale inteligente.
O altă excelentă implementare a standardului de token ERC-20 este Implementarea OpenZeppelin-20.