Как написать и развернуть NFT (часть 1 из 3 серии руководств по NFT)
Поскольку NFT привлекают всеобщее внимание к блокчейну, сейчас у вас есть отличная возможность самим разобраться в этой шумихе, опубликовав собственный контракт NFT (токен ERC-721) в блокчейне Ethereum!
Alchemy очень гордится тем, что поддерживает крупнейшие проекты в сфере NFT, включая Makersplace (недавно установивший рекорд по продаже цифровых произведений искусства на аукционе Christie's за 69 миллионов долларов), Dapper Labs (создатели NBA Top Shot и Crypto Kitties), OpenSea (крупнейший в мире NFT-маркетплейс), Zora, Super Rare, NFTfi, Foundation, Enjin, Origin Protocol, Immutable и другие.
В этом руководстве мы рассмотрим создание и развертывание смарт-контракта ERC-721 в тестовой сети Sepolia с использованием MetaMask (opens in a new tab), Solidity (opens in a new tab), Hardhat (opens in a new tab), Pinata (opens in a new tab) и Alchemy (opens in a new tab) (не волнуйтесь, если вы пока не понимаете, что все это значит — мы объясним!).
Во второй части этого руководства мы рассмотрим, как использовать наш смарт-контракт, чтобы отчеканить NFT, а в третьей части объясним, как просматривать свой NFT в MetaMask.
И, конечно, если у вас в любой момент возникнут вопросы, не стесняйтесь задавать их в Discord-канале Alchemy (opens in a new tab) или посетите документацию по NFT API от Alchemy (opens in a new tab)!
Шаг 1. Подключение к сети Ethereum
Существует множество способов отправлять запросы в блокчейн Ethereum, но для простоты мы будем использовать бесплатный аккаунт на Alchemy (opens in a new tab) — платформе для разработчиков блокчейнов и API, которая позволяет нам взаимодействовать с сетью Ethereum без необходимости запускать собственные узлы.
В этом руководстве мы также воспользуемся инструментами для разработчиков от Alchemy для мониторинга и аналитики, чтобы понять, что происходит «под капотом» при развертывании нашего смарт-контракта. Если у вас еще нет аккаунта Alchemy, вы можете бесплатно зарегистрироваться здесь (opens in a new tab).
Шаг 2. Создайте приложение (и ключ API)
Как только регистрация в Alchemy завершена, можно создать приложение и таким образом сгенерировать ключ API. Это позволит нам делать запросы к тестовой сети Sepolia. Ознакомьтесь с этим руководством (opens in a new tab), если вам интересно узнать больше о тестовых сетях.
- Перейдите к странице "Create App” в своем Alchemy Dashboard - наведите на "Apps" в навигационной панели и кликните "Create App”
- Назовите свое приложение (мы выбрали «My First NFT!»), дайте краткое описание, выберите «Ethereum» в поле Chain и «Sepolia» в поле network. После Слияния другие тестовые сети устарели.
- Нажмите "Create app" и все готово! Ваше приложение должно появиться в таблице ниже.
Шаг 3. Создайте аккаунт Ethereum (адрес)
Нам нужен аккаунт Ethereum для того, чтобы отправлять и получать транзакции. В этом руководстве мы будем использовать MetaMask, виртуальный кошелек в браузере, используемый для управления адресом вашего аккаунта Ethereum. Если вы хотите больше узнать о том, как работают транзакции в Ethereum, ознакомьтесь с этой страницей от Ethereum Foundation.
Вы можете бесплатно скачать и создать аккаунт MetaMask здесь (opens in a new tab). При создании аккаунта или если он у вас уже есть, обязательно переключитесь на «Sepolia Test Network» в правом верхнем углу (чтобы мы не работали с настоящими деньгами).
Шаг 4. Добавьте эфир из крана (Faucet)
Чтобы загрузить наш смарт контракт в тестовую сеть, нам нужно немного тестового ETH. Чтобы получить ETH, перейдите в кран Sepolia (opens in a new tab) от Alchemy, войдите в систему, введите адрес своего аккаунта и нажмите «Send Me ETH». Вскоре вы должны увидеть ETH в своем аккаунте MetaMask!
Шаг 5. Проверьте свой баланс
Чтобы перепроверить наличие баланса, давайте сделаем запрос eth_getBalance (opens in a new tab) с помощью инструмента Composer от Alchemy (opens in a new tab). Результат будет содержать сумму ETH в нашем кошельке. После ввода адреса вашего аккаунта MetaMask и нажатия «Send Request» вы должны увидеть примерно такой ответ:
1```{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}```Примечание. Этот результат указан в wei, а не в ETH. Wei это наименьшая единица измерения эфира. Конвертация из wei в ETH: 1 eth = 1018 wei. Таким образом, если мы конвертируем 0xde0b6b3a7640000 в десятичную систему, мы получим 1*1018 wei, что равно 1 ETH.
Фух! Наши ненастоящие деньги уже все там.
Шаг 6. Инициализируйте наш проект
Во-первых, надо создать директорию для нашего проекта. Перейдите в вашу командную строку и наберите:
1mkdir my-nft2cd my-nftСейчас, когда мы внутри директории нашего проекта, мы будем использовать npm init, чтобы инициализировать проект. Если у вас еще не установлен npm, следуйте этим инструкциям (opens in a new tab) (нам также понадобится Node.js (opens in a new tab), так что загрузите и его!).
1npm initНеважно, как вы ответите на вопросы при установке. Для справки, вот как это сделали мы:
1 имя пакета: (my-nft)2 версия: (1.0.0)3 описание: Мой первый NFT!4 точка входа: (index.js)5 тестовая команда:6 репозиторий git:7 ключевые слова:8 автор:9 лицензия: (ISC)10 Файл /Users/thesuperb1/Desktop/my-nft/package.json будет содержать:1112 {13 "name": "my-nft",14 "version": "1.0.0",15 "description": "Мой первый NFT!",16 "main": "index.js",17 "scripts": {18 "test": "echo \"Error: no test specified\" && exit 1"19 },20 "author": "",21 "license": "ISC"22 }Показать всеПодтвердите package.json, и мы готовы к работе!
Шаг 7. Установите Hardhat (opens in a new tab)
Hardhat - это среда для сборки, развертывания, тестирования и отладки программного обеспечения Ethereum. Он помогает разработчикам создавать смарт-контракты и децентрализованные приложения локально перед их развертыванием в основной сети.
Внутри нашего проекта my-nft выполните:
1npm install --save-dev hardhatБолее подробную информацию об инструкциях по установке (opens in a new tab) можно найти на этой странице.
Шаг 8. Создайте проект Hardhat
В директории проекта запустите:
1npx hardhatВы увидите приветственное сообщение и интерфейс с вариантами того, что делать дальше. Выберите "create an empty hardhat.config.js":
1888 888 888 888 8882888 888 888 888 8883888 888 888 888 88848888888888 8888b. 888d888 .d88888 88888b. 8888b. 8888885888 888 "88b 888P" d88" 888 888 "88b "88b 8886888 888 .d888888 888 888 888 888 888 .d888888 8887888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.8888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y8889👷 Добро пожаловать в Hardhat v2.0.11 👷10? Что вы хотите сделать? …11Создать пример проекта12❯ Создать пустой файл hardhat.config.js13ВыйтиПоказать всеЭто создаст для нас файл hardhat.config.js, в котором мы укажем все настройки для нашего проекта (в шаге 13).
Шаг 9. Добавьте папки проекта
Чтобы наш проект был организован, мы создадим две новые папки. Перейдите в командной строке в корневую директорию проекта и наберите:
1mkdir contracts2mkdir scripts-
contracts/ — здесь мы будем хранить код нашего смарт-контракта NFT
-
scripts/ — здесь мы будем хранить скрипты для развертывания и взаимодействия с нашим смарт-контрактом
Шаг 10. Напишите наш контракт
Теперь, когда наша среда настроена, перейдем к более интересным вещам: написанию кода нашего смарт-контракта!
Откройте проект my-nft в вашем любимом редакторе (нам нравится VSCode (opens in a new tab)). Смарт-контракты пишутся на языке под названием Solidity, который мы и будем использовать для написания нашего смарт-контракта MyNFT.sol.
-
Перейдите в папку
contractsи создайте новый файл с именем MyNFT.sol -
Ниже приведен код нашего смарт-контракта NFT, который основан на реализации ERC-721 из библиотеки OpenZeppelin (opens in a new tab). Скопируйте и вставьте приведенное ниже содержимое в ваш файл MyNFT.sol.
1//Контракт основан на [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)2// SPDX-License-Identifier: MIT3pragma solidity ^0.8.0;45import "@openzeppelin/contracts/token/ERC721/ERC721.sol";6import "@openzeppelin/contracts/utils/Counters.sol";7import "@openzeppelin/contracts/access/Ownable.sol";8import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";910contract MyNFT is ERC721URIStorage, Ownable {11 using Counters for Counters.Counter;12 Counters.Counter private _tokenIds;1314 constructor() ERC721("MyNFT", "NFT") {}1516 function mintNFT(address recipient, string memory tokenURI)17 public onlyOwner18 returns (uint256)19 {20 _tokenIds.increment();2122 uint256 newItemId = _tokenIds.current();23 _mint(recipient, newItemId);24 _setTokenURI(newItemId, tokenURI);2526 return newItemId;27 }28}Показать все -
Поскольку мы наследуем классы из библиотеки контрактов OpenZeppelin, в командной строке выполните
npm install @openzeppelin/contracts^4.0.0, чтобы установить библиотеку в нашу папку.
Так что же именно делает этот код? Давайте разберем его по строчкам.
Вверху нашего смарт-контракта мы импортируем три класса смарт-контрактов OpenZeppelin (opens in a new tab):
-
@openzeppelin/contracts/token/ERC721/ERC721.sol содержит реализацию стандарта ERC-721, которую унаследует наш смарт-контракт NFT. (Чтобы NFT был действительным, ваш смарт-контракт должен реализовывать все методы стандарта ERC-721). Чтобы узнать больше о наследуемых функциях ERC-721, ознакомьтесь с определением интерфейса здесь (opens in a new tab).
-
@openzeppelin/contracts/utils/Counters.sol предоставляет счетчики, которые можно увеличивать или уменьшать только на единицу. Наш смарт-контракт использует счетчик для отслеживания общего количества выпущенных NFT и для установки уникального идентификатора для нашего нового NFT. (Каждому NFT, выпущенному с помощью смарт-контракта, должен быть присвоен уникальный идентификатор — здесь наш уникальный идентификатор определяется общим количеством существующих NFT. Например, первый NFT, который мы выпускаем с помощью нашего смарт-контракта, имеет ID «1», наш второй NFT имеет ID «2» и т. д.)
-
@openzeppelin/contracts/access/Ownable.sol настраивает контроль доступа (opens in a new tab) к нашему смарт-контракту, поэтому только владелец смарт-контракта (вы) может выпускать NFT. (Обратите внимание, что включение контроля доступа — это исключительно ваше предпочтение. Если вы хотите, чтобы кто угодно мог выпустить NFT с помощью вашего смарт-контракта, удалите слово Ownable в строке 10 и onlyOwner в строке 17.)
После наших операторов импорта у нас есть наш собственный смарт-контракт NFT, который на удивление короткий — он содержит только счетчик, конструктор и одну функцию! Это благодаря нашим унаследованным контрактам OpenZeppelin, которые реализуют большинство методов, необходимых для создания NFT, таких как ownerOf, который возвращает владельца NFT, и transferFrom, который передает право собственности на NFT с одного аккаунта на другой.
В нашем конструкторе ERC-721 вы заметите, что мы передаем 2 строки: «MyNFT» и «NFT». Первая переменная — это имя смарт-контракта, а вторая — его символ. Вы можете назвать каждую из этих переменных как угодно!
Наконец, у нас есть функция mintNFT(address recipient, string memory tokenURI), которая позволяет нам выпустить NFT! Вы заметите, что эта функция принимает две переменные:
-
address recipientуказывает адрес, который получит ваш свежевыпущенный NFT -
string memory tokenURI— это строка, которая должна указывать на JSON-документ, описывающий метаданные NFT. Метаданные NFT — это то, что оживляет его, позволяя ему иметь настраиваемые свойства, такие как имя, описание, изображение и другие атрибуты. Во второй части этого руководства мы опишем, как настроить эти метаданные.
mintNFT вызывает некоторые методы из унаследованной библиотеки ERC-721 и в конечном итоге возвращает число, представляющее идентификатор только что выпущенного NFT.
Шаг 11. Подключите MetaMask и Alchemy к вашему проекту
Теперь, когда мы создали кошелек MetaMask, аккаунт Alchemy и написали наш смарт-контракт, пришло время соединить все три компонента.
Каждая транзакция, сделанная с вашего виртуального кошелька, требует подпись с использованием вашего же персонального ключа. Чтобы дать программе такую возможность, мы можем сохранить наш приватный ключ (и ключ API Alchemy) в файле окружения.
Чтобы узнать больше об отправке транзакций, ознакомьтесь с этим руководством по отправке транзакций с использованием web3.
Во-первых, установите dotenv, находясь в директории проекта:
1npm install dotenv --saveЗатем создайте файл .env в корневом каталоге нашего проекта и добавьте в него свой закрытый ключ MetaMask и URL-адрес HTTP API Alchemy.
-
Следуйте этим инструкциям (opens in a new tab), чтобы экспортировать свой закрытый ключ из MetaMask.
-
Ниже показано, как получить URL-адрес HTTP API Alchemy и скопировать его в буфер обмена.
Ваш .env теперь должен выглядеть так:
1API_URL="https://eth-sepolia.g.alchemy.com/v2/your-api-key"2PRIVATE_KEY="your-metamask-private-key"Чтобы подключить их к нашему коду, мы будем ссылаться на эти переменные в нашем файле hardhat.config.js на шаге 13.
.env! Please make sure never to share or expose your .env file with anyone, as you are compromising your secrets in doing so. If you are using version control, add your .env to a gitignore (opens in a new tab) file.Шаг 12. Установите Ethers.js
Ethers.js — это библиотека, которая упрощает взаимодействие и отправку запросов в Ethereum, оборачивая стандартные методы JSON-RPC в более удобные для пользователя методы.
Hardhat очень упрощает интеграцию плагинов (opens in a new tab) для дополнительных инструментов и расширенной функциональности. Мы воспользуемся преимуществами плагина Ethers (opens in a new tab) для развертывания контракта (Ethers.js (opens in a new tab) имеет несколько очень удобных методов развертывания контрактов).
В директории проекта запустите:
1npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0Так же в следующем шаге мы добавим ethers в hardhat.config.js.
Шаг 13. Обновите hardhat.config.js
Мы добавили несколько зависимостей и плагинов, а сейчас мы должны обновить hardhat.config.js, чтобы наш проект узнал об этих изменениях.
Измените ваш hardhat.config.js, чтобы он выглядел примерно так:
1 /**2 * @type import('hardhat/config').HardhatUserConfig3 */4 require('dotenv').config();5 require("@nomiclabs/hardhat-ethers");6 const { API_URL, PRIVATE_KEY } = process.env;7 module.exports = {8 solidity: "0.8.1",9 defaultNetwork: "sepolia",10 networks: {11 hardhat: {},12 sepolia: {13 url: API_URL,14 accounts: [`0x${PRIVATE_KEY}`]15 }16 },17 }Показать всеШаг 14. Скомпилируйте наш контракт
Пора заставить это работать, давайте скомпилируем наш контракт. Задача compile это одна из встроенных в Hardhat задач.
Запустите в командной строке:
1npx hardhat compileМожет появиться предупреждение вроде SPDX license identifier not provided in source file, но об этом не стоит беспокоиться - надеемся все остальное выглядит хорошо! Если нет, вы всегда можете написать в Discord-канал Alchemy (opens in a new tab).
Шаг 15. Напишите наш скрипт развертывания
Контракт написан, файл конфигурации корректен, пора писать скрипт развертывания.
Перейдите в папку scripts/ и создайте новый файл с именем deploy.js, добавив в него следующее содержимое:
1async function main() {2 const MyNFT = await ethers.getContractFactory("MyNFT")34 // Начинаем развертывание, возвращая промис, который разрешается в объект контракта5 const myNFT = await MyNFT.deploy()6 await myNFT.deployed()7 console.log("Контракт развернут по адресу:", myNFT.address)8}910main()11 .then(() => process.exit(0))12 .catch((error) => {13 console.error(error)14 process.exit(1)15 })Показать всеHardhat отлично объясняет, что делает каждая из этих строк кода, в своем руководстве по контрактам (opens in a new tab), мы использовали их объяснения здесь.
1const MyNFT = await ethers.getContractFactory("MyNFT");ContractFactory в ethers.js — это абстракция, используемая для развертывания новых смарт-контрактов, поэтому MyNFT здесь является фабрикой для экземпляров нашего контракта NFT. При использовании плагина hardhat-ethers экземпляры ContractFactory и Contract по умолчанию связаны с первым подписавшим.
1const myNFT = await MyNFT.deploy();Вызов deploy() на ContractFactory запустит развертывание, и вернет Promise, который разрешается в Contract. Это объект, который имеет метод для каждой из функций нашего смарт контракта.
Шаг 16. Разверните наш контракт
Мы наконец-то готовы развернуть наш смарт контракт! Вернитесь в корневой каталог вашего проекта и в командной строке выполните:
1npx hardhat --network sepolia run scripts/deploy.jsВы должны увидеть что-то наподобие:
1Контракт развернут по адресу: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650Если мы перейдем в обозреватель блоков Sepolia Etherscan (opens in a new tab) и найдем наш контракт по адресу, то сможем убедиться, что он был успешно развернут. Если вы не видите его сразу, подождите некоторое время, так как это может занять некоторое время. Транзакция будет выглядеть примерно так:
Адрес в поле «From» (От) должен совпадать с адресом вашего аккаунта MetaMask, а в поле «To» (Кому) будет указано «Contract Creation» (Создание контракта). Если мы нажмем на транзакцию, то увидим адрес нашего контракта в поле «To»:
Да-а-а-а! Вы только что развернули свой смарт-контракт NFT в сети Ethereum (тестовой сети)!
Чтобы понять, что происходит «под капотом», давайте перейдем на вкладку Explorer в нашей панели управления Alchemy (opens in a new tab). Если у вас несколько приложений Alchemy, убедитесь, что вы отфильтровали их по приложению и выбрали «MyNFT».
Вы увидите пачку вызовов JSON-RPC, которые произвел Hardhat/Ethers после того, как мы запустили функцию .deploy(). Здесь стоит отметить два важных вызова: eth_sendRawTransaction, который является запросом на фактическую запись нашего смарт-контракта в сеть Sepolia, и eth_getTransactionByHash, который является запросом на чтение информации о нашей транзакции по ее хешу (типичный шаблон при отправке транзакций). Чтобы узнать больше об отправке транзакций, ознакомьтесь с этим руководством по отправке транзакций с использованием Web3.
На этом первая часть этого руководства закончена. Во второй части мы будем взаимодействовать с нашим смарт-контрактом, отчеканивая NFT, а в третьей части мы покажем, как просматривать свои NFT в кошельке Ethereum!
Последнее обновление страницы: 5 декабря 2025 г.






