Пространство Web3 движется быстро! Это здорово, однако это означает, что в большинстве руководств по созданию токенов ERC-20 используются устаревшие версии и устаревшие функции (например, Тестовая сеть Ринкеби). Итак, вот обновленный вариант, написанный в ноябре 2022 года…

Вот что мы будем делать:

  • Использовать OpenZeppelinбезопасные и проверенные сообществом контракты для создания токена ERC-20.
  • Использовать Трюфельнабор инструментов для компиляции и локального развертывания контракта в сети Ethereum, а затем взаимодействия с различными методами.
  • использовать ТолстыйПлатформа инфраструктуры Web3 для развертывания контракта на Герли тестовая сеть.
  • Найдите недавно развернутый токен на Этерскан & импортировать токены в Метамаск.


Настройка проекта

Предпосылка: Установите Truffle (на момент написания этого я использую truffle@5.6.3):
npm install -g truffle

Примечание: Ради этой демонстрации я буду называть токен MyTokenпоэтому всякий раз, когда я ссылаюсь MyTokenзамените его на то, что вы хотите, чтобы ваше имя токена было.

1) Инициализируйте голый шаблон проекта и cd внутрь:
truffle init MyToken && cd MyToken

2) Установите OpenZeppelin, чтобы мы могли использовать их смарт-контракты:
npm install @openzeppelin/contracts

3) Откройте проект в выбранном вами редакторе (скорее всего code . если вы используете VSCode, используйте любой ярлык, который вы установили, или откройте его вручную)


Создание токена

Посмотрите на структуру проекта, и вы заметите следующее:

contracts/: Каталог контрактов Solidity
migrations/: Каталог для файлов развертывания с поддержкой сценариев.
test/: Каталог тестовых файлов для тестирования вашего приложения и контрактов.
truffle.js: конфигурационный файл Truffle

Создайте файл внутри contracts/ называется MyToken.sol. .sol расширение означает Солидностьобъектно-ориентированный язык для реализации смарт-контрактов, который мы будем использовать.

В рамках MyToken.sol добавьте следующее:

MyToken.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
Войти в полноэкранный режим

Выйти из полноэкранного режима

  • Первая строка показывает, какой идентификатор лицензии использует контракт. Идентификаторы лицензий SPDX были введены в v0.6.8.
  • pragma — это директива, указывающая, какую версию компилятора следует использовать в файле.
  • Строка импорта импортирует содержимое этот файл который доступен в нашем node_modules от установки OpenZeppelin ранее.

Теперь пришло время создать контракт:

MyToken.sol

// ...

contract MyToken is ERC20 {
    constructor(
        string memory name,
        string memory symbol,
        uint initialSupply
    ) ERC20(name, symbol) {
        require(initialSupply > 0, "Initial supply has to be greater than 0");
        _mint(msg.sender, initialSupply * 10**18);
    }
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Некоторые примечания к вышеизложенному:

  • Контракт наследование из контракта OpenZeppelin ERC20 с is ключевое слово.
  • Конструктор принимает name, symbolа также initialSupply который мы будем передавать из развертывателя позже.
  • После быстрой проверки с использованием requireмы используем _mint функция, унаследованная от OpenZeppelin для выпуска токенов.
  • initialSupply * 10**18 представляет баланс с 18 десятичными знаками. Почему? Поскольку десятичные дроби не поддерживаются Solidity и EVM. Точно так же, как 1 ETH представлен 10 ^ 18 своей натуральной единицы (1 эфир = 1 000 000 000 000 000 000 Wei), мы будем делать то же самое для нашего токена. Это позволяет нам отправлять произвольные суммы (например, 0,0004 MyToken).


Настройка трюфеля

В недавно созданном проекте Truffle есть много шаблонов, которые помогут вам начать работу, вы можете сократить их до этого:

truffle-config.js

require("dotenv").config();
const { MNEMONIC, PROJECT_ID } = process.env;

const HDWalletProvider = require("@truffle/hdwallet-provider");

module.exports = {
    networks: {
        development: {
            host: "127.0.0.1", // Localhost (default: none)
            port: 9545, // Standard Ethereum port (default: none)
            network_id: "*", // Any network (default: none)
        },
        goerli: {
            provider: () =>
                new HDWalletProvider(
                    MNEMONIC,
                    `https://goerli.infura.io/v3/${PROJECT_ID}`,
                ),
            network_id: 5, // Goerli's id
            confirmations: 2, // # of confirmations to wait between deployments. (default: 0)
            timeoutBlocks: 200, // # of blocks before a deployment times out  (minimum/default: 50)
            skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
        },
    },
    compilers: {
        solc: {
            version: "0.8.17",
        },
    },
};
Войти в полноэкранный режим

Выйти из полноэкранного режима

Следующий:
1) Установите HDWalletProvider:
npm install @truffle/hdwallet-provider.

2) Установить дотенв:
npm install dotenv.

3) Создайте .env файл в корне каталога проекта со следующим содержимым:

MNEMONIC=
PROJECT_ID=
Войти в полноэкранный режим

Выйти из полноэкранного режима

(Не забудьте добавить .env файл на ваш .gitignore!)

Пришло время заполнить MNEMONIC & PROJECT_ID ценности…


Получение МНЕМОНИКИ из MetaMask

Предпосылка: Установите браузер MetaMask из если вы еще не получили его.

1) Следить эти инструкции чтобы раскрыть секретную фразу восстановления. Примечание: сделать нет поделитесь этим ключом с кем-либо или сохраните его в Интернете в любом месте.

2) Скопируйте значение в соответствующий MNEMONIC ключ в .env файл.


Получение PROJECT_ID от Infura

1) Зарегистрируйтесь на (это бесплатно!)

2) После подтверждения и входа в систему нажмите кнопку «СОЗДАТЬ НОВЫЙ КЛЮЧ» в правом верхнем углу панели инструментов. Введите Name и выберите Web3 API как сеть, а затем создать.

3) Выберите Görli в разделе «Конечные точки сети»:
Скриншот Инфура

4) Скопируйте идентификатор, который находится в URL-адресе HTTPS, в соответствующий PROJECT_ID ключ в .env файл.


Создание миграции

Чтобы развернуть контракт, вам нужно создать файл в migrations/ папка:

1_initial_migration.js

const MyToken = artifacts.require("MyToken");

module.exports = (deployer) => {
    deployer.deploy(MyToken, "MyToken", "MYT", 100000);
};
Войти в полноэкранный режим

Выйти из полноэкранного режима

Некоторые примечания к вышеизложенному:

  • Мы сообщаем Truffle, с какими контрактами мы хотели бы взаимодействовать, через artifacts.require() метод. Имя должно совпадать с именем определения контракта в этом исходном файле, а не в исходном файле (поскольку файлы могут содержать более одного контракта).
  • API развертывания (deployer.deploy(contract, args..., options)) можно найти здесь. Мы передаем контракт, за которым следуют необязательные аргументы конструктора.
  • Аргументы конструктора "MyToken" (название), "MYT" (символ) и 100000 (первоначальная поставка).

Это должно быть все для конфигурации! ⚙️


Локальное развертывание контракта

Чтобы развернуть смарт-контракт, нам нужно подключиться к блокчейну. Truffle имеет встроенный персональный блокчейн, который можно использовать для тестирования. Этот блокчейн является локальным для вашей системы и не взаимодействует с основной сетью Ethereum.

1) Откройте окно терминала и cd в каталог вашего проекта Truffle.

2) Бежать truffle develop который запустит локальную сеть Ethereum.

3) Беги compile который скомпилирует файлы контракта Solidity, что должно дать вам что-то вроде этого:

truffle(develop)> compile

Compiling your contracts...
===========================
> Compiling ./contracts/MyToken.sol
> Compiling @openzeppelin/contracts/token/ERC20/ERC20.sol
> Compiling @openzeppelin/contracts/token/ERC20/IERC20.sol
> Compiling @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
> Compiling @openzeppelin/contracts/utils/Context.sol
> Artifacts written to /Users/ME/MyToken/build/contracts
> Compiled successfully using:
   - solc: 0.8.17+commit.8d345f5f.Emscripten.clang
truffle(develop)>
Войти в полноэкранный режим

Выйти из полноэкранного режима

Примечание. Как указано в сообщении об успешном завершении, артефакты были созданы в вашем /build/contracts каталог. Имя сгенерированного артефакта .json files отражают не имя исходного файла, а имя определения контракта.

5) Наконец, запустите migrate --reset для развертывания вашего контракта в локальной сети.

--reset запускает все миграции с самого начала, а не с последней завершенной миграции

Взаимодействие с токеном

Пришло время сделать некоторые базовые проверки, чтобы убедиться, что все работает так, как ожидалось:

1) Бежать token = await MyToken.deployed(); чтобы получить доступ к TruffleContract. Это также должно вывести полный экземпляр контракта со всеми доступными методами, свойствами и т. д.

2) Отсюда мы можем протестировать несколько методов:

truffle(develop)> name = await token.name();
'MyToken'
truffle(develop)> symbol = await token.symbol();
'MYT'
truffle(develop)> decimals = (await token.decimals()).toString()
'18'
Войти в полноэкранный режим

Выйти из полноэкранного режима

Я призываю вас экспериментировать с другими доступными методами!


Развертывание контракта в тестовой сети Goerli

Прежде чем вы сможете развернуть контракт на Goerli, нам понадобится несколько эфиров тестовой сети! Прежде всего, переключитесь на сеть Goerli на вашем MetaMask (если это не вариант для вас, вам может потребоваться включить опцию «Показать тестовые сети» в дополнительных настройках):

Скриншот метамаски

Затем отправляйтесь в https://goerlifaucet.com, введите свой адрес и нажмите кнопку «Отправить мне ETH». Как только транзакция будет подтверждена, проверьте свой MetaMask, чтобы подтвердить, что ETH прибыл, если нет — попробуйте другой сборщик.

Время мигрировать! Бежать migrate --reset --network goerliкоторый должен вывести что-то вроде этого:

truffle(develop)> migrate --reset --network goerli

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.


Starting migrations...
======================
> Network name:    'goerli'
> Network id:      5
> Block gas limit: 30000000 (0x1c9c380)


1_initial_migration.js
======================

   Deploying 'MyToken'
   -------------------
   > transaction hash:    0x31b69373bdfdabb20e205746150d5c4845b363e9a3755450d23adbad1a736c04
   > Blocks: 1            Seconds: 4
   > contract address:    0x904609375980165691D587386A0163aa7d8D00A6
   > block number:        7875096
   > block timestamp:     1667350704
   > account:             0xEb390e921A349e2434871D989c9AD74bB8de10c0
   > balance:             0.047005278846168288
   > gas used:            1186096 (0x121930)
   > gas price:           2.524855622 gwei
   > value sent:          0 ETH
   > total cost:          0.002994721153831712 ETH

   Pausing for 2 confirmations...

   -------------------------------
   > confirmation number: 1 (block: 7875097)
   > confirmation number: 2 (block: 7875098)
   > Saving artifacts
   -------------------------------------
   > Total cost:     0.002994721153831712 ETH

Summary
=======
> Total deployments:   1
> Final cost:          0.002994721153831712 ETH
Войти в полноэкранный режим

Выйти из полноэкранного режима


Просмотр контракта на Etherscan

В моем случае вы увидите как часть выходных данных миграции, что адрес контракта: 0x904609375980165691D587386A0163aa7d8D00A6. Используя это, мы можем перейти к Этерскан для просмотра созданного договора!

Страница Etherscan MyToken


Добавление токена в MetaMask

Используя тот же адрес контракта, вернитесь в MetaMask и нажмите «Импортировать токен». При вводе адреса контракта символ и десятичные знаки должны заполниться автоматически:

Скриншот формы MetaMask

и после нажатия «Добавить пользовательский токен»…

Скриншот баланса MetaMask

вы должны видеть свой баланс! 🪄

Вот и все! 🏁

Если вам интересно узнать больше о Solidity, Крипто-зомби отличное место для начала. Солидность на собственном примере также есть хорошие удобоваримые реальные примеры того, куда могут пойти смарт-контракты.