Читать книгу Криптовалюта с нуля: От идеи до запуска вашего блокчейн проекта. Часть 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. В следующем разделе мы развернем этот контракт в нашей тестовой сети и начнем с ним взаимодействовать.

Криптовалюта с нуля: От идеи до запуска вашего блокчейн проекта. Часть 2

Подняться наверх