Читать книгу Криптовалюта с нуля: От идеи до запуска вашего блокчейн проекта. Часть 2 - Иван Алексеевич Евдокимов - Страница 7
Часть 2: Техническая реализация (Практическое руководство)
Глава 5: Создание токена на Ethereum (стандарт ERC-20)
5.6 Практикум: Шаг за шагом создаем токен "BookCoin".
ОглавлениеЭто пошаговое руководство, которое проведет вас через весь процесс создания, тестирования и развертывания вашего первого ERC-20 токена.
Предварительные требования
Установленное ПО:
· Node.js (v16 или выше)
· npm
· Git
· MetaMask (браузерное расширение)
Аккаунты:
· Infura (бесплатный аккаунт)
· Etherscan (бесплатная регистрация)
· Alchemy (для получения тестовых ETH)
Шаг 1: Инициализация проекта
bash
# Создаем папку проекта
mkdir bookcoin-token
cd bookcoin-token
# Инициализируем npm проект
npm init -y
# Устанавливаем Truffle глобально
npm install -g truffle
# Инициализируем Truffle проект
truffle init
# Устанавливаем необходимые зависимости
npm install @openzeppelin/contracts @truffle/hdwallet-provider dotenv
Проверка структуры проекта:
bookcoin-token/
├── contracts/
│ └── Migrations.sol
├── migrations/
│ └── 1_initial_migration.js
├── test/
├── node_modules/
├── truffle-config.js
└── package.json
Шаг 2: Создание контракта BookCoin
В папке contracts/ создайте файл BookCoin.sol:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title BookCoin
* @dev ERC-20 токен для книги о создании криптовалют
*/
contract BookCoin is ERC20, Ownable {
/**
* @dev Конструктор создает все токены и отправляет создателю
* @param initialSupply Начальное предложение токенов (в целых единицах)
*/
constructor(uint256 initialSupply) ERC20("BookCoin", "BOOK") {
_mint(msg.sender, initialSupply * 10 ** decimals());
_transferOwnership(msg.sender);
}
/**
* @dev Функция для создания дополнительных токенов (только владельцем)
* @param to Адрес получателя
* @param amount Количество токенов для создания
*/
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
/**
* @dev Функция для сжигания токенов
* @param amount Количество токенов для сжигания
*/
function burn(uint256 amount) public {
_burn(msg.sender, amount);
}
}
Шаг 3: Настройка конфигурации
Замените содержимое truffle-config.js:
javascript
const HDWalletProvider = require('@truffle/hdwallet-provider');
require('dotenv').config();
module.exports = {
networks: {
// Локальная разработка с Ganache
development: {
host: "127.0.0.1",
port: 7545,
network_id: "*"
},
// Sepolia testnet (рекомендуемая)
sepolia: {
provider: () => new HDWalletProvider({
privateKeys: [process.env.PRIVATE_KEY],
providerOrUrl: `https://sepolia.infura.io/v3/${process.env.INFURA_PROJECT_ID}`
}),
network_id: 11155111,
gas: 5500000,
gasPrice: 20000000000,
confirmations: 2,
timeoutBlocks: 200,
skipDryRun: true
}
},
compilers: {
solc: {
version: "0.8.19",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
}
},
// Для верификации на Etherscan
plugins: ['truffle-plugin-verify'],
api_keys: {
etherscan: process.env.ETHERSCAN_API_KEY
}
};
Шаг 4: Настройка переменных окружения
Создайте файл .env в корне проекта:
env
# Ваш приватный ключ из MetaMask (НИКОМУ НЕ ПОКАЗЫВАЙТЕ!)
PRIVATE_KEY=ваш_приватный_ключ_без_0x
# Infura Project ID
INFURA_PROJECT_ID=ваш_infura_project_id
# Etherscan API Key
ETHERSCAN_API_KEY=ваш_etherscan_api_key
Как получить приватный ключ:
1. Откройте MetaMask
2. Выберите аккаунт → "Account details" → "Export Private Key"
Внимание! Добавьте .env в .gitignore!
Шаг 5: Создание миграционного файла
В папке migrations/ создайте 2_deploy_bookcoin.js:
javascript
const BookCoin = artifacts.require("BookCoin");
module.exports = async function (deployer) {
// 1,000,000 токенов с 18 десятичными знаками
const initialSupply = "1000000";
console.log("Деплой BookCoin с начальным предложением:", initialSupply);
await deployer.deploy(BookCoin, initialSupply);
const bookCoin = await BookCoin.deployed();
console.log(" BookCoin успешно развернут!");
console.log(" Адрес контракта:", bookCoin.address);
console.log(" Владелец:", await bookCoin.owner());
console.log(" Общее предложение:", (await bookCoin.totalSupply()).toString());
console.log(" Символ:", await bookCoin.symbol());
console.log(" Название:", await bookCoin.name());
};
Шаг 6: Компиляция контракта
bash
truffle compile
Ожидаемый результат:
Compiling your contracts…
===========================
> Compiling ./contracts/BookCoin.sol
> Compiling ./contracts/Migrations.sol
> Compiling @openzeppelin/contracts/access/Ownable.sol
> Compiling @openzeppelin/contracts/token/ERC20/ERC20.sol
> Artifacts written to /path/to/build/contracts
> Compiled successfully using:
– solc: 0.8.19
Шаг 7: Получение тестовых ETH
1. Перейдите на sepoliafaucet.com
2. Войдите через аккаунт Alchemy (бесплатная регистрация)
3. Вставьте ваш адрес MetaMask
4. Получите 0.5 Sepolia ETH
Альтернативные краны:
· poinfrastructure.com/faucet
· faucet.quicknode.com/ethereum/sepolia
Шаг 8: Деплой в сеть Sepolia
bash
truffle migrate –network sepolia
Ожидаемый вывод:
Starting migrations…
> Network name: 'sepolia'
> Network id: 11155111
1_initial_migration.js
======================
Deploying 'Migrations'
Transactions: 0x1234…5678
2_deploy_bookcoin.js
====================
Deploying 'BookCoin'
Transactions: 0x5678…9012
BookCoin успешно развернут!
Адрес контракта: 0xAbC…123
Владелец: 0xYourAddress
Общее предложение: 1000000000000000000000000
Символ: BOOK
Название: BookCoin
Summary
=======
> Total deployments: 2
> Final cost: 0.035 ETH
Шаг 9: Проверка в блок-эксплорере
Откройте в браузере (замените YOUR_CONTRACT_ADDRESS):
https://sepolia.etherscan.io/address/YOUR_CONTRACT_ADDRESS
Вы должны увидеть:
· Подтвержденную транзакцию
· Контракт с состоянием "Contract Source Code Not Verified"
Шаг 10: Верификация контракта
Установите плагин для верификации:
bash
npm install -D truffle-plugin-verify
Выполните верификацию:
bash
truffle run verify BookCoin –network sepolia
Ожидаемый результат:
Verifying BookCoin
Pass – Verified: https://sepolia.etherscan.io/address/0xYOUR_CONTRACT#code
Successfully verified 1 contract(s).
Шаг 11: Взаимодействие с контрактом
Через Truffle Console:
bash
truffle console –network sepolia
javascript
// Получить экземпляр контракта
const bookCoin = await BookCoin.deployed()
// Проверить общее предложение
const totalSupply = await bookCoin.totalSupply()
console.log("Total Supply:", totalSupply.toString())
// Проверить баланс владельца
const accounts = await web3.eth.getAccounts()
const ownerBalance = await bookCoin.balanceOf(accounts[0])
console.log("Owner Balance:", web3.utils.fromWei(ownerBalance, 'ether'))
// Перевести 10 BOOK другому адресу
const recipient = "0x742d35Cc6634C0532925a3b8Dc9F1a…"
await bookCoin.transfer(recipient, web3.utils.toWei("10", "ether"))
// Проверить баланс получателя
const recipientBalance = await bookCoin.balanceOf(recipient)
console.log("Recipient Balance:", web3.utils.fromWei(recipientBalance, 'ether'))
Шаг 12: Добавление токена в MetaMask
1. Откройте MetaMask
2. Нажмите "Import tokens"
3. Введите адрес контракта (остальное подтянется автоматически)
4. Нажмите "Add Custom Token"
Теперь вы видите свои BOOK токены!
Шаг 13: Тестирование основных функций
Через Etherscan:
1. Перейдите на страницу вашего контракта
2. Откройте вкладку "Write Contract"
3. Подключите MetaMask
4. Протестируйте функции:
· transfer – перевод токенов
· approve – разрешение на расходование
· burn – сжигание токенов
Шаг 14: Создание простого теста
В папке test/ создайте bookcoin.test.js:
javascript
const BookCoin = artifacts.require("BookCoin");
contract("BookCoin", (accounts) => {
const [owner, user1, user2] = accounts;
const initialSupply = web3.utils.toWei("1000000", "ether");
it("должен развернуть контракт с правильным начальным предложением", async () => {
const instance = await BookCoin.deployed();
const totalSupply = await instance.totalSupply();
assert.equal(totalSupply.toString(), initialSupply, "Неправильное начальное предложение");
});
it("должен отправлять все токены владельцу", async () => {
const instance = await BookCoin.deployed();
const ownerBalance = await instance.balanceOf(owner);
assert.equal(ownerBalance.toString(), initialSupply, "Владелец должен получить все токены");
});
it("должен позволять перевод токенов", async () => {
const instance = await BookCoin.deployed();
const transferAmount = web3.utils.toWei("100", "ether");
await instance.transfer(user1, transferAmount, { from: owner });
const user1Balance = await instance.balanceOf(user1);
assert.equal(user1Balance.toString(), transferAmount, "Получатель должен получить токены");
});
});
Запуск тестов:
bash
truffle test
Итоги практикума
Вы создали:
· Полнофункциональный ERC-20 токен
· Безопасный контракт с использованием OpenZeppelin
· Настроенную среду разработки
Вы развернули:
· В тестовой сети Sepolia
· С верификацией исходного кода
· С возможностью взаимодействия через Etherscan
Вы получили:
· Практический опыт работы с Truffle
· Навыки работы с тестовыми сетями
· Понимание процесса деплоя смарт-контрактов
Дополнительные задания
1. Добавьте кастомные функции в контракт:
· Функцию паузы
· Механизм сжигания комиссий
· Whitelist для определенных операций
2. Создайте простой dApp для взаимодействия с токеном:
· Веб-интерфейс для перевода токенов
· Отображение балансов
· История транзакций
3. Настройте CI/CD для автоматического деплоя:
· Используйте GitHub Actions
· Автоматизируйте тестирование и деплой
Поздравляю! Вы успешно создали и развернули свой первый ERC-20 токен. Этот фундаментальный навык открывает дорогу к созданию более сложных DeFi-проектов и dApp.