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

Стандарт токенов ERC-20

Последнее обновление страницы: 26 февраля 2026 г.

Введение

Что такое токен?

Токены в Ethereum могут представлять практически все, что угодно:

  • баллы репутации на онлайн-платформе
  • навыки персонажа в игре
  • финансовые активы, такие как доля в компании
  • фиатная валюта, как доллар США
  • унция золота
  • и многое другое...

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

Что такое ERC-20?

ERC-20 вводит стандарт для взаимозаменяемых токенов, другими словами, они обладают свойством, которое делает каждый токен точно таким же (по типу и ценности), как и другой токен. Например, токен ERC-20 действует точно так же, как ETH, означая, что 1 токен всегда равен и всегда будет равен всем остальным токенам.

Предварительные условия

Тело

ERC-20 (Ethereum Request for Comments 20), предложенный Фабианом Фогельстеллером в ноябре 2015 года, является стандартом токенов, который реализует API для токенов в смарт-контрактах.

Примеры функциональности, которую предоставляет ERC-20:

  • перевод токенов с одного аккаунта на другой
  • узнать текущий баланс токенов на счету
  • узнать количество доступных токенов в сети
  • подтвердить, может ли сумма токена со счета быть потрачена аккаунтом третьей стороны

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

Из EIP-20 (opens in a new tab):

Методы

1function name() public view returns (string)
2function symbol() public view returns (string)
3function decimals() public view returns (uint8)
4function totalSupply() public view returns (uint256)
5function balanceOf(address _owner) public view returns (uint256 balance)
6function transfer(address _to, uint256 _value) public returns (bool success)
7function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
8function approve(address _spender, uint256 _value) public returns (bool success)
9function allowance(address _owner, address _spender) public view returns (uint256 remaining)
Показать все

События

1event Transfer(address indexed _from, address indexed _to, uint256 _value)
2event Approval(address indexed _owner, address indexed _spender, uint256 _value)

Примеры

Давайте разберемся почему Стандарт настолько важен, чтобы упростить для нас проверку любого контракта токена ERC-20 в Ethereum. Нам просто нужен двоичный интерфейс приложения контракта (ABI) для создания интерфейса для любого токена ERC-20. Как вы можете увидеть ниже, мы будем использовать упрощенный ABI, чтобы сделать пример простым.

Пример Web3.py

Во-первых, убедитесь, что вы установили библиотеку Python Web3.py (opens in a new tab):

1pip install web3
1from web3 import Web3
2
3
4w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))
5
6dai_token_addr = "0x6B175474E89094C44Da98b954EedeAC495271d0F" # DAI
7weth_token_addr = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" # Обернутый эфир (WETH)
8
9acc_address = "0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11" # Uniswap V2: DAI 2
10
11# Это упрощенный двоичный интерфейс приложения (ABI) контракта токена ERC-20.
12# Он будет предоставлять только методы: balanceOf(address), decimals(), symbol() и totalSupply()
13simplified_abi = [
14 {
15 'inputs': [{'internalType': 'address', 'name': 'account', 'type': 'address'}],
16 'name': 'balanceOf',
17 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
18 'stateMutability': 'view', 'type': 'function', 'constant': True
19 },
20 {
21 'inputs': [],
22 'name': 'decimals',
23 'outputs': [{'internalType': 'uint8', 'name': '', 'type': 'uint8'}],
24 'stateMutability': 'view', 'type': 'function', 'constant': True
25 },
26 {
27 'inputs': [],
28 'name': 'symbol',
29 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
30 'stateMutability': 'view', 'type': 'function', 'constant': True
31 },
32 {
33 'inputs': [],
34 'name': 'totalSupply',
35 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
36 'stateMutability': 'view', 'type': 'function', 'constant': True
37 }
38]
39
40dai_contract = w3.eth.contract(address=w3.to_checksum_address(dai_token_addr), abi=simplified_abi)
41symbol = dai_contract.functions.symbol().call()
42decimals = dai_contract.functions.decimals().call()
43totalSupply = dai_contract.functions.totalSupply().call() / 10**decimals
44addr_balance = dai_contract.functions.balanceOf(acc_address).call() / 10**decimals
45
46# DAI
47print("===== %s =====" % symbol)
48print("Общее предложение:", totalSupply)
49print("Баланс адреса:", addr_balance)
50
51weth_contract = w3.eth.contract(address=w3.to_checksum_address(weth_token_addr), abi=simplified_abi)
52symbol = weth_contract.functions.symbol().call()
53decimals = weth_contract.functions.decimals().call()
54totalSupply = weth_contract.functions.totalSupply().call() / 10**decimals
55addr_balance = weth_contract.functions.balanceOf(acc_address).call() / 10**decimals
56
57# WETH
58print("===== %s =====" % symbol)
59print("Общее предложение:", totalSupply)
60print("Баланс адреса:", addr_balance)
Показать все

Известные проблемы

Проблема с получением токенов ERC-20

По состоянию на 20.06.2024 из-за этой проблемы было потеряно токенов ERC-20 на сумму не менее 83 656 418 долларов США. Обратите внимание, что чистая реализация ERC-20 подвержена этой проблеме, если вы не примените набор дополнительных ограничений поверх стандарта, перечисленных ниже.

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

  1. Механизм перевода токенов
  • Токены ERC-20 переводятся с помощью функций transfer или transferFrom
    • Когда пользователь отправляет токены на адрес контракта с помощью этих функций, токены переводятся независимо от того, предназначен ли принимающий контракт для их обработки
  1. Отсутствие уведомления
    • Принимающий контракт не получает уведомления или обратного вызова о том, что на него были отправлены токены
    • Если в принимающем контракте отсутствует механизм для обработки токенов (например, резервная функция или специальная функция для управления приемом токенов), токены фактически застревают на адресе контракта
  2. Отсутствие встроенной обработки
    • Стандарт ERC-20 не включает обязательную функцию для реализации принимающими контрактами, что приводит к ситуации, когда многие контракты не могут должным образом управлять входящими токенами

Возможные решения

Хотя полностью предотвратить эту проблему с ERC-20 невозможно, существуют методы, которые позволяют значительно снизить вероятность потери токенов для конечного пользователя:

  • Наиболее распространенная проблема возникает, когда пользователь отправляет токены на адрес самого контракта токена (например, USDT, депонированный на адрес контракта токена USDT). Рекомендуется ограничить функцию transfer(..) , чтобы отменять такие попытки перевода. Рассмотрите возможность добавления проверки require(_to != address(this)); в реализацию функции transfer(..).
  • Функция transfer(..) в целом не предназначена для внесения токенов на контракты. approve(..) и шаблон transferFrom(..)используется для внесения токенов ERC-20 на контракты. Можно ограничить функцию перевода, чтобы запретить с ее помощью вносить токены на любые контракты, однако это может нарушить совместимость с контрактами, которые предполагают, что токены могут быть депонированы на контракты с помощью функцииtrasnfer(..)` (например, пулы ликвидности Uniswap).
  • Всегда предполагайте, что токены ERC-20 могут оказаться в вашем контракте, даже если ваш контракт не должен их получать. Не существует способа предотвратить или отклонить случайные пополнения на стороне получателя. Рекомендуется реализовать функцию, которая позволит извлекать случайно депонированные токены ERC-20.
  • Рассмотрите возможность использования альтернативных стандартов токенов.

В результате этой проблемы появились некоторые альтернативные стандарты, такие как ERC-223 или ERC-1363.

Дополнительные материалы

Другие стандарты взаимозаменяемых токенов

Была ли эта статья полезной?