Перейти к основному содержанию

Понимание смарт-контракта токена ERC-20

Умные контракты
токенов
Solidity
erc-20
Beginner
jdourlens
5 апреля 2020 г.
4 минута прочтения

Один из наиболее важных стандартов смарт-контрактов в Ethereum известен как ERC-20, который стал техническим стандартом, используемым для всех смарт-контрактов в блокчейне Ethereum для реализации взаимозаменяемых токенов.

ERC-20 определяет общий список правил, которым должны соответствовать все взаимозаменяемые токены Ethereum. Следовательно, этот стандарт токенов позволяет разработчикам всех типов точно предсказывать, как новые токены будут функционировать в более крупной системе Ethereum. Это упрощает и облегчает задачи разработчиков, потому что они могут продолжать свою работу, зная, что им не придется переделывать каждый новый проект при выпуске нового токена, если он соответствует правилам.

Ниже в виде интерфейса представлены функции, которые должен реализовывать ERC-20. Если вы не знаете, что такое интерфейс, прочтите нашу статью об объектно-ориентированном программировании в 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}
Показать все

Ниже приведено построчное объяснение назначения каждой функции. После этого мы представим простую реализацию токена ERC-20.

Геттеры

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

Возвращает количество существующих токенов. Эта функция является геттером и не изменяет состояние контракта. Имейте в виду, что в Solidity нет чисел с плавающей запятой. Поэтому в большинстве токенов используется 18 десятичных знаков, и общее предложение и другие результаты будут возвращаться в следующем виде: 1000000000000000000 для 1 токена. Не у каждого токена 18 десятичных знаков, и на это действительно нужно обращать внимание при работе с токенами.

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

Возвращает количество токенов, принадлежащих адресу (account). Эта функция является геттером и не изменяет состояние контракта.

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

Стандарт ERC-20 позволяет адресу предоставить разрешение другому адресу на получение с него токенов. Этот геттер возвращает оставшееся количество токенов, которые spender сможет потратить от имени owner. Эта функция является геттером, не изменяет состояние контракта и по умолчанию должна возвращать 0.

Функции

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

Перемещает amount токенов с адреса вызывающего функцию (msg.sender) на адрес получателя. Эта функция генерирует событие Transfer, которое будет определено позже. Возвращает true, если перевод был возможен.

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

Устанавливает allowance — количество токенов, которое spender может перевести с баланса вызывающего функцию (msg.sender). Эта функция генерирует событие Approval. Функция возвращает значение, указывающее, было ли разрешение успешно установлено.

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

Перемещает amount токенов от sender к recipient с помощью механизма разрешений. Затем amount вычитается из разрешенной суммы (allowance) для вызывающего. Эта функция генерирует событие Transfer.

События

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

Это событие генерируется, когда определенное количество (value) токенов отправляется с адреса from на адрес to.

В случае выпуска новых токенов перевод обычно происходит from нулевого адреса (0x00..0000), а в случае сжигания токенов перевод происходит to нулевой адрес (0x00..0000).

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

Это событие генерируется, когда определенное количество (value) токенов одобрено owner для использования spender.

Базовая реализация токенов ERC-20

Вот самый простой код, который можно взять за основу для вашего токена 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}
Показать все

Другой отличной реализацией стандарта токенов ERC-20 является реализация ERC-20 от OpenZeppelin (opens in a new tab).

Последнее обновление страницы: 21 августа 2025 г.

Было ли это руководство полезным?