Читать книгу Криптовалюта с нуля: От идеи до запуска вашего блокчейн проекта. Часть 2 - Иван Алексеевич Евдокимов - Страница 3
Часть 2: Техническая реализация (Практическое руководство)
Глава 5: Создание токена на Ethereum (стандарт ERC-20)
5.2 Написание смарт-контракта на Solidity.
ОглавлениеТеперь, когда среда настроена, мы переходим к самому важному – созданию смарт-контракта нашего токена. Мы будем использовать язык Solidity и библиотеку OpenZeppelin – золотой стандарт безопасности в разработке смарт-контрактов.
1. Создание проекта и структуры папок
Откройте терминал и выполните:
bash
# Создаем папку для проекта
mkdir my-erc20-token
cd my-erc20-token
# Инициализируем новый проект Truffle
truffle init
# Устанавливаем OpenZeppelin Contracts
npm install @openzeppelin/contracts
После выполнения команд структура папок будет выглядеть так:
my-erc20-token/
├── contracts/
│ └── Migrations.sol
├── migrations/
│ └── 1_initial_migration.js
├── test/
├── node_modules/
├── truffle-config.js
└── package.json
2. Создание контракта токена
В папке contracts/ создайте новый файл BookCoin.sol:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Импортируем стандарт ERC-20 из OpenZeppelin
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract BookCoin is ERC20 {
/**
* @dev Конструктор, который вызывается при деплое контракта
* @param initialSupply – начальное предложение токенов
*
* – Наследуем от ERC20 и передаем имя и символ токена
* – Вызываем _mint чтобы создать начальное предложение
* – Умножаем на 10^decimals() чтобы учесть десятичные разряды
*/
constructor(uint256 initialSupply) ERC20("BookCoin", "BOOK") {
_mint(msg.sender, initialSupply * 10 ** decimals());
}
}
3. Детальное объяснение кода
Строка 1: Лицензия
solidity
// SPDX-License-Identifier: MIT
Обязательная строка, указывающая лицензию вашего кода. MIT – популярный выбор с минимальными ограничениями.
Строка 2: Версия компилятора
solidity
pragma solidity ^0.8.0;
Указывает, что код должен компилироваться компилятором версии 0.8.0 или выше, но ниже 0.9.0. Версия 0.8.0 ввела важные улучшения безопасности.
Строка 5: Импорт библиотеки
solidity
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
Импортируем готовую, проаудитированную реализацию стандарта ERC-20 из OpenZeppelin. Это избавляет нас от написания сотен строк кода и предотвращает множество уязвимостей.
Строка 7: Объявление контракта
solidity
contract BookCoin is ERC20 {
Создаем наш контракт BookCoin, который наследует все функции от ERC20.
Строки 8-16: Конструктор
solidity
constructor(uint256 initialSupply) ERC20("BookCoin", "BOOK") {
_mint(msg.sender, initialSupply * 10 ** decimals());
}
· constructor – специальная функция, которая выполняется один раз при деплое контракта.
· uint256 initialSupply – параметр, который мы передадим при деплое (например, 1000000 для 1 миллиона токенов).
· ERC20("BookCoin", "BOOK") – вызов конструктора родительского класса с именем и символом токена.
· _mint(msg.sender, initialSupply * 10 ** decimals()) – создание токенов:
· _mint – внутренняя функция ERC-20 для создания новых токенов.
· msg.sender – адрес, который разворачивает контракт (получает все токены).
· initialSupply * 10 ** decimals() – преобразуем целое число в значение с десятичными разрядами. По умолчанию decimals() возвращает 18, так что 1000 токенов станут 1000 × 10¹⁸ = 1000000000000000000000.
4. Что мы получаем "из коробки"?
Наследуя от OpenZeppelin ERC-20, наш токен автоматически получает:
· Базовый функционал ERC-20:
· totalSupply() – общее предложение токенов
· balanceOf(account) – баланс конкретного адреса
· transfer(recipient, amount) – перевод токенов на другой адрес
· allowance(owner, spender) – проверка разрешенной суммы
· approve(spender, amount) – разрешение другому адресу тратить ваши токены
· transferFrom(sender, recipient, amount) – перевод токенов от имени владельца
· События (Events):
· Transfer(from, to, value) – при переводе токенов
· Approval(owner, spender, value) – при выдаче разрешения
· Безопасность:
· Проверка на переполнение (overflow/underflow)
· Валидация адресов
· Защита от front-running атак
5. Компиляция контракта
Убедитесь, что Ganache запущен, затем в терминале выполните:
bash
truffle compile
При успешной компиляции вы увидите:
Compiling your contracts…
===========================
> Compiling ./contracts/BookCoin.sol
> Compiling ./contracts/Migrations.sol
> Compiling @openzeppelin/contracts/token/ERC20/ERC20.sol
# … другие файлы OpenZeppelin
> Artifacts written to /Users/…/build/contracts
> Compiled successfully using:
– solc: 0.8.19+commit.7dd6d404.Emscripten.clang
6. Расширенная версия с дополнительными функциями.
Если вы хотите добавить больше функциональности, вот улучшенная версия:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract BookCoin is ERC20, Ownable {
uint8 private _decimals;
constructor(
uint256 initialSupply,
string memory name,
string memory symbol,
uint8 decimalUnits
) ERC20(name, symbol) {
_decimals = decimalUnits;
_mint(msg.sender, initialSupply * 10 ** decimalUnits);
_transferOwnership(msg.sender);
}
function decimals() public view virtual override returns (uint8) {
return _decimals;
}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
function burn(uint256 amount) public {
_burn(msg.sender, amount);
}
}
Что добавилось:
· Ownable – добавляет модификатор onlyOwner для функций, которые могут вызываться только владельцем контракта.
· Настраиваемые decimals – возможность установить другое количество десятичных знаков (например, 6 как в USDC).
· Функция mint – создание дополнительных токенов (только владельцем).
· Функция burn – сжигание токенов.
Проверка безопасности
Никогда не делайте так:
solidity
// ОПАСНО! Не используйте устаревшие версии
pragma solidity ^0.4.0;
// ОПАСНО! Не пишите ERC-20 с нуля
contract MyToken {
mapping(address => uint256) balances;
// … сотни строк ненадежного кода
}
Всегда делайте так:
· Используйте Solidity ≥ 0.8.0
· Наследуйтесь от OpenZeppelin
· Проводите аудит перед запуском в mainnet
Вывод: Мы создали безопасный, полностью функциональный токен ERC-20 всего в 10 строках кода, благодаря использованию OpenZeppelin. В следующем разделе мы развернем этот контракт в нашей тестовой сети и начнем с ним взаимодействовать.