ERC-20 — это интерфейс, не реализация. Шесть обязательных функций (totalSupply, balanceOf, transfer, transferFrom, approve, allowance) и два события (Transfer, Approval). Всё остальное — детали реализации, которые имеют значение. Наш опыт — более 50 запущенных в продакшн ERC-20 токенов — показывает, что именно эти детали определяют, будет ли токен совместим с DeFi-протоколами, или его придётся переписывать.
Какой подход к разработке ERC-20 токена выбрать?
Первая дилемма — апгрейдируемый (Proxy + Implementation) или immutable. Proxy даёт гибкость в изменениях, но каждая транзакция через delegatecall стоит около 150 000 gas вместо 45 000 для обычного контракта. Immutable контракты в три раза дешевле для пользователей и проще в аудите. Рекомендация: для utility токенов и governance — immutable, для DeFi vaults и сложных протоколов — upgradeable с осторожностью.
Вторая проблема — контроль эмиссии. Если minter — EOA, это централизованный риск: ключ утечёт или владелец напечатает неограниченное количество. Решение — использовать multisig или смарт-контракт с ролью MINTER. Наши проекты всегда используют AccessControl для распределённого управления.
Третья — gas оптимизация. Неиспользование ERC20Permit (EIP-2612) заставляет пользователя тратить две транзакции вместо одной для первого взаимодействия с DeFi.
Почему стоит использовать OpenZeppelin, а не писать с нуля?
OpenZeppelin — стандарт индустрии. Их код прошел сотни аудитов, используется в миллионах контрактов. Не пишите ERC-20 с нуля — это увеличивает риск ошибок и снижает доверие интеграторов. Наши решения базируются на OpenZeppelin с дополнительными кастомными модулями.
Базовая реализация
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; contract MyToken is ERC20, ERC20Burnable, ERC20Permit, Ownable2Step { uint256 public constant MAX_SUPPLY = 100_000_000 * 10**18; // 100M токенов constructor( address initialOwner, address treasury ) ERC20("My Token", "MTK") ERC20Permit("My Token") Ownable2Step() { _transferOwnership(initialOwner); _mint(treasury, MAX_SUPPLY); // весь supply при деплое } } ERC20Permit — важное расширение: позволяет approve с помощью off-chain подписи. Это улучшает UX (одна транзакция вместо двух) и снижает газ для пользователя. Ownable2Step вместо Ownable защищает от случайной передачи контроля на неверный адрес.
Mintable токен с контролем доступа
Если токен должен выпускаться после деплоя, используем AccessControl:
import "@openzeppelin/contracts/access/AccessControl.sol"; contract MintableToken is ERC20, ERC20Burnable, ERC20Permit, AccessControl { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); uint256 public immutable maxSupply; constructor( string memory name, string memory symbol, uint256 _maxSupply, address admin ) ERC20(name, symbol) ERC20Permit(name) { maxSupply = _maxSupply; _grantRole(DEFAULT_ADMIN_ROLE, admin); _grantRole(MINTER_ROLE, admin); } function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) { require(totalSupply() + amount <= maxSupply, "Exceeds max supply"); _mint(to, amount); } } MINTER_ROLE должен быть назначен смарт-контракту (staking reward, vesting), а не EOA.
Сравнение подходов
| Критерий | Immutable контракт | Upgradeable proxy |
|---|---|---|
| Газ (транзакция) | ~45 000 gas | ~150 000 gas (из-за delegatecall) |
| Гибкость | Нет изменений | Можно обновлять логику |
| Риск | Только логические ошибки | Ошибки в proxy, storage collision |
| Аудит | Проще | Сложнее (два контракта) |
| Рекомендация | Utility, governance | DeFi vaults, сложные протоколы |
Почему decimals должны быть 18 (обычно)
По умолчанию decimals = 18 (как ETH). Исключение: USDC/USDT используют 6. Если создаёте stablecoin или wrap — проверьте decimals оригинала. Никогда не используйте 0 decimals для токенов, которые будут торговаться на DEX — AMM плохо работает с целыми числами. Мы сталкивались с проектами, где неправильный decimals приводил к ошибкам совместимости с протоколами.
Распространённые ошибки
Transfer tax: каждый transfer берёт процент — ломает DeFi протоколы. Если всё же нужен, используйте whitelist для контрактов Uniswap, Aave, Compound. Centralised blacklist без timelock: для community токена — плохо. Reentrancy в transfer hooks: если добавляете _beforeTokenTransfer или _afterTokenTransfer, убедитесь, что не вызываете внешний код.
Этапы работы
| Этап | Длительность | Результат |
|---|---|---|
| Аналитика | 1-2 дня | Спецификация токена, выбор архитектуры |
| Реализация | 2-5 дней | Смарт-контракт, тесты, скрипты деплоя |
| Аудит | 1-3 недели | Отчёт об уязвимостях, исправления |
| Деплой и верификация | 1 день | Контракт в цепочке, проверенный на Etherscan |
| Поддержка | 1 месяц | Бесплатные правки после запуска |
Верификация и деплой
# Тесты forge test -vvv # Деплой с верификацией forge script script/Deploy.s.sol \ --rpc-url $RPC_URL \ --private-key $PRIVATE_KEY \ --broadcast \ --verify \ --etherscan-api-key $ETHERSCAN_KEY После деплоя — верифицируйте контракт на Etherscan/Polygonscan. Неверифицированный токен вызывает законное подозрение у бирж и пользователей.
Что входит в разработку ERC-20 токена под ключ
- Смарт-контракт на Solidity с кастомными функциями (mint, burn, permit, pause, blacklist)
- Модульные тесты (Foundry/Hardhat) с покрытием >90%
- Скрипты деплоя и настройка под вашу сеть (Ethereum, Polygon, Arbitrum, BNB Chain)
- Верификация на блокчейн-эксплорере (Etherscan, Polygonscan)
- Документация для разработчиков и пользователей
- Консультация по интеграции с DeFi-протоколами
- Гарантия — 1 месяц бесплатных правок после запуска
Оценим ваш проект за 1 рабочий день. Мы — команда senior-блокчейн-разработчиков: 5+ лет на рынке, 50+ реализованных токенов. Свяжитесь с нами, чтобы обсудить детали и заказать разработку ERC-20 токена под ключ.







