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

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

ERC-721
Alchemy
Мова програмування Solidity
Смарт-контракти
Початківець
Sumi Mudgil
22 квітня 2021 р.
13 читається за хвилину

Оскільки 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 за допомогою MetaMaskopens in a new tab, Solidityopens in a new tab, Hardhatopens in a new tab, Pinataopens in a new tab та Alchemyopens in a new tab (не хвилюйтеся, якщо ви ще не розумієте, що все це означає — ми пояснимо!).

У 2-му розділі цього підручника ми поговоримо про те, як ми можемо використовувати смарт-контракти для утворення NFT, та в 3-му розділі ми пояснимо, як переглядати ваш NFT в MetaMask.

І, звісно, якщо у вас виникнуть запитання, не соромтеся звертатися до Alchemy Discordopens in a new tab або відвідати документацію Alchemy з NFT APIopens in a new tab!

Крок 1. Підключення до мережі Ethereum

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

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

Крок 2. Створіть свій застосунок (та ключ API)

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

  1. Перейдіть на сторінку "Створити додаток" на панелі управління Alchemy, навівши курсор на "Додатки" в рядку на панелі навігації та натиснувши на "Створити додаток"

Створіть свій застосунок

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

Налаштуйте та опублікуйте свій застосунок

  1. Натисніть "Створити додаток", ось і все! Ваш додаток повинен з'явитися у таблиці нижче.

Крок 3. Створіть обліковий запис Ethereum (адресу)

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

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

Установіть Sepolia як свою мережу

Крок 4. Додайте ефір (ether) із крана (Faucet)

Для того, щоб розгорнути наш смартконтракт на тестову мережу, нам знадобляться підроблені ETH. Щоб отримати ETH, ви можете перейти до крана Sepoliaopens in a new tab, який розміщено на Alchemy, увійти в систему та ввести адресу свого облікового запису, а потім натиснути «Надіслати мені ETH» (Send Me ETH). Ви повинні побачити ETH у вашому обліковому записі MetaMask найближчим часом!

Крок 5. Перевірте свій баланс

Щоб перевірити, чи є у нас баланс, давайте зробимо запит eth_getBalanceopens in a new tab за допомогою інструмента-композитора від Alchemyopens in a new tab. Це поверне кількість ETH в ваш гаманець. Після введення вашої адреси облікового запису MetaMask і натисніть кнопку "Відправити запит", ви повинні побачити таку відповідь:

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

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

Фух! Наші "гроші" все ще там.

Крок 6. Ініціалізуйте наш проєкт

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

1mkdir my-nft
2cd my-nft

Тепер, коли ми всередині нашої папки для проєкту, ми будемо використовувати npm для ініціалізації проєкту. Якщо у вас ще не встановлено npm, дотримуйтесь цих інструкційopens in a new tab (нам також знадобиться Node.jsopens 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:
11
12 {
13 "name": "my-nft",
14 "version": "1.0.0",
15 "description": "Мій перший NFT!",
16 "main": "index.js",
17 "scripts": {
18 "test": "echo \"Помилка: тест не вказано\" && exit 1"
19 },
20 "author": "",
21 "license": "ISC"
22 }
Показати все

Затвердіть package.json, і ми готові рухатися далі!

Крок 7. Установіть Hardhatopens in a new tab

Hardhat є середовищем розробки для компіляції, розгортання, тестування та налагодження вашого програмного забезпечення Ethereum. Це допомагає розробникам створювати смарт-контракти та dapp локально перед розгортанням у реальний ланцюжок.

Всередині нашого проекту my-nft запущено:

1npm install --save-dev hardhat

Перегляньте цю сторінку, щоб дізнатися більше про інструкції з установкиopens in a new tab.

Крок 8. Створіть проєкт Hardhat

Всередині папки проєкту запустіть:

1npx hardhat

Потім ви маєте побачити вітальне повідомлення та вибір подальших бажаних дій. Оберіть "Створити порожній hardhat.config.js":

1888 888 888 888 888
2888 888 888 888 888
3888 888 888 888 888
48888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
5888 888 "88b 888P" d88" 888 888 "88b "88b 888
6888 888 .d888888 888 888 888 888 888 .d888888 888
7888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
8888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
9👷 Ласкаво просимо до Hardhat v2.0.11 👷‍
10? Що ви хочете зробити? …
11Створити зразок проєкту
12❯ Створити порожній hardhat.config.js
13Вийти
Показати все

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

Крок 9. Додайте папки проєкту

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

1mkdir contracts
2mkdir scripts
  • contracts/ - це місце, де ми будемо зберігати наш NFT код смарт-контракту

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

Крок 10. Напишіть наш контракт

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

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

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

  2. Нижче наведено код нашого смарт-контракту NFT, який ми заснували на реалізації ERC-721 з бібліотеки OpenZeppelinopens 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: MIT
    3pragma solidity ^0.8.0;
    4
    5import "@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";
    9
    10contract MyNFT is ERC721URIStorage, Ownable {
    11 using Counters for Counters.Counter;
    12 Counters.Counter private _tokenIds;
    13
    14 constructor() ERC721("MyNFT", "NFT") {}
    15
    16 function mintNFT(address recipient, string memory tokenURI)
    17 public onlyOwner
    18 returns (uint256)
    19 {
    20 _tokenIds.increment();
    21
    22 uint256 newItemId = _tokenIds.current();
    23 _mint(recipient, newItemId);
    24 _setTokenURI(newItemId, tokenURI);
    25
    26 return newItemId;
    27 }
    28}
    Показати все
  3. Оскільки ми успадковуємо класи з бібліотеки контрактів OpenZeppelin, у вашому командному рядку виконайте npm install @openzeppelin/contracts^4.0.0, щоб установити бібліотеку в нашу папку.

Отже, що саме робить цей код? Давайте розберемо все по пунктах.

У верхній частині нашого смарт-контракту ми імпортуємо три класи смарт-контрактів OpenZeppelinopens in a new tab:

  • @openzeppelin/контракти/токен/ERC721/ERC721.sol містить впровадження стандарту ERC-721, який наш смарт-контракт NFT успадкує. (Аби бути дійсним NFT, Ваш смарт-контракт повинен реалізувати всі методи стандарту ERC-721.) Щоб дізнатися більше про успадковані функції ERC-721, перегляньте визначення інтерфейсу тутopens in a new tab.

  • @openzeppelin/контракти/utils/Counters.sol надає лічильники, які можуть бути збільшені або зменшені лише на одиницю. Наш смарт-контракт використовує лічильник, щоб відстежувати загальну кількість NFT, яка оцінюється, і встановити унікальний ідентифікатор у нашому новому NFT. (Для кожного NFT, створеного за допомогою смарт-контракту, повинен бути призначений унікальний ID - тут наш унікальний ID просто визначається загальною кількістю існуюючих NFT. Наприклад, перший NFT, який ми створили зі смарт-контрактом, містить ідентифікатор "1", другий NFT має ідентифікатор "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 - це дійсно те, що втілює його до життя, дозволяючи йому мати налаштовані властивості, такі як ім’я, опис, зображення та інші атрибути. У 2-й частині цього уроку ми розкажемо, як налаштувати ці метадані.

mintNFT викликає деякі методи з успадкованої бібліотеки ERC-721 і в кінцевому підсумку повертає число, яке представляє ідентифікатор щойно викарбуваного NFT.

Крок 11. Підключіть MetaMask і Alchemy до свого проєкту

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

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

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

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

1npm install dotenv --save

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

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

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

Скопіюйте URL-адресу вашого Alchemy API

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

1API_URL="https://eth-sepolia.g.alchemy.com/v2/your-api-key"
2PRIVATE_KEY="your-metamask-private-key"

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

Крок 12. Установіть Ethers.js

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

Hardhat значно спрощує інтеграцію плагінівopens in a new tab для додаткових інструментів та розширеної функціональності. Ми скористаємося плагіном Ethersopens in a new tab для розгортання контракту (Ethers.jsopens 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').HardhatUserConfig
3 */
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. Скомпілюйте наш контракт

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

З командного рядка запустіть:

1npx hardhat compile

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

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

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

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

1async function main() {
2 const MyNFT = await ethers.getContractFactory("MyNFT")
3
4 // Початок розгортання, повертає проміс, який вирішується в об'єкт контракту
5 const myNFT = await MyNFT.deploy()
6 await myNFT.deployed()
7 console.log("Контракт розгорнуто за адресою:", myNFT.address)
8}
9
10main()
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");

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

1const myNFT = await MyNFT.deploy();

Виклик розгортання () на Фабриці контрактів розпочне розгортання і поверне Проміс (Обіцянку), яка розв'язує контракт. Це об'єкт, у якого є метод для кожної з наших функцій смартконтракту.

Крок 16. Розгорніть наш контракт

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

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

Тоді ви повинні побачити щось на кшталт:

1Контракт розгорнуто за адресою: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650

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

Перегляньте адресу вашої транзакції на Etherscan

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

Перегляньте адресу вашого контракту на Etherscan

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

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

Перегляд викликів, зроблених «під капотом», за допомогою панелі Explorer від Alchemy

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

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

Останні оновлення сторінки: 5 грудня 2025 р.

Чи була ця інструкція корисною?