Перейти до основного вмісту

Як написати та розгорнути NFT (Частина 1/3 серії посібників про NFT)

ERC-721
Alchemy
Solidity
смарт-контракти
Для початківців
Сумі Мудгіл
22 квітня 2021 р.
12 хвилин на читання

Оскільки NFT привертають увагу громадськості до блокчейну, зараз чудова нагода самостійно зрозуміти цей ажіотаж, опублікувавши власний контракт NFT (токен ERC-721) у блокчейні Етеріум!

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 за допомогою МетаМаск (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 у МетаМаск.

І, звісно, якщо у вас виникнуть запитання на будь-якому етапі, не соромтеся звертатися до Discord Alchemy (opens in a new tab) або відвідайте документацію NFT API від Alchemy (opens in a new tab)!

Крок 1: Підключення до мережі Етеріум

Існує багато способів робити запити до блокчейну Етеріум, але для спрощення ми використаємо безкоштовний акаунт на Alchemy (opens in a new tab) — платформі для розробників блокчейну та API, яка дозволяє нам взаємодіяти з ланцюгом Етеріум без необхідності запускати власні вузли.

У цьому посібнику ми також скористаємося інструментами розробника Alchemy для моніторингу та аналітики, щоб зрозуміти, як технічно відбувається розгортання нашого смарт-контракту. Якщо у вас ще немає акаунта Alchemy, ви можете безкоштовно зареєструватися тут (opens in a new tab).

Крок 2: Створення застосунку (та ключа API)

Після створення акаунта Alchemy ви можете згенерувати ключ API, створивши застосунок. Це дозволить нам робити запити до тестової мережі Sepolia. Перегляньте цей посібник (opens in a new tab), якщо хочете дізнатися більше про тестові мережі.

  1. Перейдіть на сторінку «Create App» (Створити застосунок) на панелі керування Alchemy, навівши курсор на «Apps» (Застосунки) на навігаційній панелі та натиснувши «Create App».

Create your app

  1. Назвіть свій застосунок (ми вибрали «My First NFT!»), додайте короткий опис, виберіть «Ethereum» для ланцюга (Chain) та «Sepolia» для вашої мережі (Network). Після Злиття інші тестові мережі були застарілими.

Configure and publish your app

  1. Натисніть «Create app» — і все! Ваш застосунок має з'явитися в таблиці нижче.

Крок 3: Створення акаунта (адреси) Етеріум

Нам потрібен акаунт Етеріум для надсилання та отримання транзакцій. Для цього посібника ми використаємо МетаМаск — віртуальний гаманець у браузері, який використовується для керування адресою вашого акаунта Етеріум. Якщо ви хочете дізнатися більше про те, як працюють транзакції в Етеріумі, перегляньте цю сторінку від Фундації Ethereum.

Ви можете безкоштовно завантажити та створити акаунт МетаМаск тут (opens in a new tab). Під час створення акаунта, або якщо він у вас уже є, обов'язково перемкніться на «Sepolia Test Network» у верхньому правому куті (щоб ми не мали справи з реальними грошима).

Set Sepolia as your network

Крок 4: Отримання етеру з крана

Щоб розгорнути наш смарт-контракт у тестовій мережі, нам знадобиться трохи тестового ETH. Щоб отримати ETH, ви можете перейти до крана Sepolia (opens in a new tab), який підтримується Alchemy, увійти в систему, ввести адресу свого акаунта та натиснути «Send Me ETH». Незабаром після цього ви побачите ETH у своєму акаунті МетаМаск!

Крок 5: Перевірка балансу

Щоб переконатися, що наш баланс на місці, давайте зробимо запит eth_getBalance (opens in a new tab) за допомогою інструмента пісочниці Alchemy (opens in a new tab). Це поверне кількість ETH у нашому гаманці. Після того, як ви введете адресу свого акаунта МетаМаск і натиснете «Send Request», ви побачите таку відповідь:

{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}

Примітка Цей результат у Wei, а не в ETH. Wei використовується як найменший номінал етеру. Перетворення з Wei в ETH: 1 ETH = 1018 Wei. Отже, якщо ми переведемо 0xde0b6b3a7640000 у десяткову систему, ми отримаємо 1*1018 Wei, що дорівнює 1 ETH.

Хух! Наші несправжні гроші на місці.

Крок 6: Ініціалізація нашого проєкту

Спочатку нам потрібно створити папку для нашого проєкту. Перейдіть до командного рядка та введіть:

mkdir my-nft cd my-nft

Тепер, коли ми знаходимося всередині папки нашого проєкту, ми використаємо npm init для ініціалізації проєкту. Якщо у вас ще не встановлено npm, дотримуйтесь інструкцій зі встановлення Node.js (opens in a new tab) (нам знадобляться Node.js та npm для цього посібника).

npm init

Не має особливого значення, як ви відповідатимете на запитання під час встановлення; ось як ми це зробили для довідки:

Схваліть package.json, і ми готові до роботи!

Крок 7: Встановлення Hardhat (opens in a new tab)

Hardhat — це середовище розробки для компіляції, розгортання, тестування та зневадження вашого програмного забезпечення для Етеріуму. Воно допомагає розробникам під час створення смарт-контрактів та децентралізованих застосунків (dapp) локально перед розгортанням у робочому ланцюзі.

Усередині нашого проєкту my-nft виконайте:

npm install --save-dev hardhat

Перегляньте цю сторінку для отримання додаткової інформації щодо інструкцій зі встановлення (opens in a new tab).

Крок 8: Створення проєкту Hardhat

Усередині папки нашого проєкту виконайте:

npx hardhat

Після цього ви побачите вітальне повідомлення та можливість вибрати, що ви хочете зробити. Виберіть «create an empty hardhat.config.js»:

888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 888 888 "88b 888P" d88" 888 888 "88b "88b 888 888 888 .d888888 888 888 888 888 888 .d888888 888 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 👷 Welcome to Hardhat v2.0.11 👷‍ ? What do you want to do? … Create a sample project ❯ Create an empty hardhat.config.js Quit

Це згенерує для нас файл hardhat.config.js, у якому ми вкажемо всі налаштування для нашого проєкту (на кроці 13).

Крок 9: Додавання папок проєкту

Щоб підтримувати порядок у нашому проєкті, ми створимо дві нові папки. Перейдіть до кореневого каталогу вашого проєкту в командному рядку та введіть:

mkdir contracts mkdir scripts

  • contracts/ — тут ми зберігатимемо код нашого смарт-контракту NFT

  • scripts/ — тут ми зберігатимемо скрипти для розгортання та взаємодії з нашим смарт-контрактом

Крок 10: Написання нашого контракту

Тепер, коли наше середовище налаштовано, перейдемо до цікавішого: написання коду нашого смарт-контракту!

Відкрийте проєкт my-nft у вашому улюбленому редакторі (нам подобається VSCode (opens in a new tab)). Смарт-контракти пишуться мовою Solidity, яку ми й використаємо для написання нашого смарт-контракту MyNFT.sol.‌

  1. Перейдіть до папки contracts та створіть новий файл із назвою MyNFT.sol

  2. Нижче наведено код нашого смарт-контракту NFT, який ми базували на реалізації ERC-721 з бібліотеки ОупенЗеппелін (opens in a new tab). Скопіюйте та вставте наведений нижче вміст у ваш файл MyNFT.sol.

  3. Оскільки ми успадковуємо класи з бібліотеки контрактів ОупенЗеппелін, у командному рядку виконайте npm install @openzeppelin/contracts^4.0.0, щоб встановити бібліотеку в нашу папку.

Отже, що саме робить цей код? Давайте розберемо його рядок за рядком.

У верхній частині нашого смарт-контракту ми імпортуємо три класи смарт-контрактів ОупенЗеппелін (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, який ми карбуємо за допомогою нашого смарт-контракту, має ідентифікатор «1», наш другий NFT має ідентифікатор «2» тощо).

  • @openzeppelin/contracts/access/Ownable.sol налаштовує контроль доступу (opens in a new tab) до нашого смарт-контракту, тому лише власник смарт-контракту (ви) може карбувати NFT. (Зауважте, що включення контролю доступу є виключно питанням уподобань. Якщо ви хочете, щоб будь-хто міг викарбувати NFT за допомогою вашого смарт-контракту, видаліть слово Ownable у рядку 10 та onlyOwner у рядку 17).

Після наших інструкцій імпорту ми маємо наш власний смарт-контракт NFT, який напрочуд короткий — він містить лише лічильник, конструктор та одну функцію! Це завдяки нашим успадкованим контрактам ОупенЗеппелін, які реалізують більшість методів, необхідних для створення 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: Підключення МетаМаск та Alchemy до вашого проєкту

Тепер, коли ми створили гаманець МетаМаск, акаунт Alchemy та написали наш смарт-контракт, настав час об'єднати їх.

Кожна транзакція, надіслана з вашого віртуального гаманця, вимагає підпису за допомогою вашого унікального приватного ключа. Щоб надати нашій програмі цей дозвіл, ми можемо безпечно зберігати наш приватний ключ (та ключ API Alchemy) у файлі середовища.

Щоб дізнатися більше про надсилання транзакцій, перегляньте цей посібник з надсилання транзакцій за допомогою Web3.

Спочатку встановіть пакет dotenv у каталозі вашого проєкту:

npm install dotenv --save

Потім створіть файл .env у кореневому каталозі нашого проєкту та додайте до нього свій приватний ключ МетаМаск і URL-адресу HTTP API Alchemy.

  • Дотримуйтесь цих інструкцій (opens in a new tab), щоб експортувати свій приватний ключ із МетаМаск

  • Дивіться нижче, щоб отримати URL-адресу HTTP API Alchemy та скопіювати її в буфер обміну

Copy your Alchemy API URL

Ваш .env тепер має виглядати так:

API_URL="https://eth-sepolia.g.alchemy.com/v2/your-api-key (opens in a new tab)" PRIVATE_KEY="your-metamask-private-key"

Щоб фактично підключити їх до нашого коду, ми пошлемося на ці змінні у нашому файлі hardhat.config.js на кроці 13.

Не робіть коміт файлу .env! Будь ласка, ніколи нікому не передавайте та не показуйте свій файл .env, оскільки так ви розкриваєте свої секретні дані. Якщо ви використовуєте систему контролю версій, додайте свій .env до файлу gitignore (opens in a new tab).

Крок 12: Встановлення Ethers.js

Ethers.js — це бібліотека, яка полегшує взаємодію та виконання запитів до Етеріуму, обгортаючи стандартні методи JSON-RPC більш зручними для користувача методами.

Hardhat дозволяє дуже легко інтегрувати плагіни (opens in a new tab) для додаткових інструментів та розширеної функціональності. Ми скористаємося плагіном Ethers (opens in a new tab) для розгортання контракту (Ethers.js (opens in a new tab) має кілька дуже зручних методів розгортання контрактів).

У каталозі вашого проєкту введіть:

npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0

Нам також знадобиться ethers у нашому hardhat.config.js на наступному кроці.

Крок 13: Оновлення hardhat.config.js

Наразі ми додали кілька залежностей та плагінів, тепер нам потрібно оновити hardhat.config.js, щоб наш проєкт знав про них усі.

Оновіть ваш hardhat.config.js, щоб він виглядав так:

Крок 14: Компіляція нашого контракту

Щоб переконатися, що все працює, давайте скомпілюємо наш контракт. Завдання компіляції є одним із вбудованих завдань Hardhat.

З командного рядка виконайте:

npx hardhat compile

Ви можете отримати попередження про те, що ідентифікатор ліцензії SPDX не вказано у вихідному файлі, але не варто про це турбуватися — сподіваємося, все інше виглядає добре! Якщо ні, ви завжди можете написати в Discord Alchemy (opens in a new tab).

Крок 15: Написання нашого скрипта розгортання

Тепер, коли наш контракт написано, а файл конфігурації готовий до роботи, настав час написати скрипт розгортання нашого контракту.

Перейдіть до папки scripts/ та створіть новий файл із назвою deploy.js, додавши до нього такий вміст:

Hardhat чудово пояснює, що робить кожен із цих рядків коду, у своєму посібнику з контрактів (opens in a new tab), ми запозичили їхні пояснення тут.

const MyNFT = await ethers.getContractFactory("MyNFT");

ContractFactory в Ethers.js — це абстракція, яка використовується для розгортання нових смарт-контрактів, тому MyNFT тут є фабрикою для екземплярів нашого контракту NFT. Під час використання плагіна hardhat-ethers екземпляри ContractFactory та Contract за замовчуванням підключаються до першого підписанта.

const myNFT = await MyNFT.deploy();

Виклик deploy() у ContractFactory розпочне розгортання та поверне Promise, який вирішується в Contract. Це об'єкт, який має метод для кожної з функцій нашого смарт-контракту.

Крок 16: Розгортання нашого контракту

Ми нарешті готові розгорнути наш смарт-контракт! Поверніться до кореня каталогу вашого проєкту та в командному рядку виконайте:

npx hardhat --network sepolia run scripts/deploy.js

Після цього ви побачите щось на зразок:

Contract deployed to address: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650

Якщо ми перейдемо до Etherscan для Sepolia (opens in a new tab) та знайдемо адресу нашого контракту, ми зможемо побачити, що його було успішно розгорнуто. Якщо ви не бачите його відразу, зачекайте трохи, оскільки це може зайняти деякий час. Транзакція виглядатиме приблизно так:

View your transaction address on Etherscan

Адреса «From» (Від) має збігатися з адресою вашого акаунта МетаМаск, а в адресі «To» (Кому) буде вказано «Contract Creation» (Створення контракту). Якщо ми натиснемо на транзакцію, ми побачимо адресу нашого контракту в полі «To»:

View your contract address on Etherscan

Ура! Ви щойно розгорнули свій смарт-контракт NFT у ланцюзі Етеріум (тестовій мережі)!

Щоб зрозуміти, як це працює технічно, перейдіть на вкладку «Explorer» (Провідник) на нашій панелі керування Alchemy (opens in a new tab). Якщо у вас є кілька застосунків Alchemy, обов'язково відфільтруйте за застосунком і виберіть «MyNFT».

View calls made “under the hood” with Alchemy’s Explorer Dashboard

Тут ви побачите кілька викликів JSON-RPC, які Hardhat/Ethers зробили для нас у фоновому режимі, коли ми викликали функцію .deploy(). Два важливі виклики, на які слід звернути увагу, — це eth_sendRawTransaction, який є запитом на фактичний запис нашого смарт-контракту в ланцюг Sepolia, та eth_getTransactionByHash, який є запитом на читання інформації про нашу транзакцію за заданим хешем (типовий патерн під час надсилання транзакцій). Щоб дізнатися більше про надсилання транзакцій, перегляньте цей посібник із надсилання транзакцій за допомогою Web3.

Це все для першої частини цього посібника. У другій частині ми фактично взаємодіятимемо з нашим смарт-контрактом, карбуючи NFT, а в третій частині ми покажемо вам, як переглянути ваш NFT у вашому гаманці Етеріум!