Моя первая NFT-коллекция на Solidity + Hardhat — «Сизифов Труд» +22


Введение

На момент написания статьи я работаю Frontend-разработчиком в VK (Delivery Club) на Vue и плавно перехожу на iOS-разработку. Уже около 4 лет считаю себя поверхностно приближенным к сфере крипты: участвовал в разработке P2P-платформы (BTC-обменника), изучал основы и идеологию, инвестировал, терял деньги на фьючерсах — все, как надо.

Однажды, по интернету стала расходиться новость о том, что 12-летний мальчик заработал ~$350,000 на коллекции программно-сгенерированных китов, состоящей из 3350 уникальных айтемов.

https://opensea.io/collection/weirdwhales
https://opensea.io/collection/weirdwhales

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

Необходимые ссылки будут указаны по ходу статьи, а в конце приложен репозиторий с кодом для полноценного минтинга своих NFT.

Подготовка

Я являюсь большим фанатом фентези-средневековья (Толкин, Сапковский), поэтому первое, что пришло мне в голову — гоблины. Гоблины, которые могут быть вооружены мечами и копьями, а облачены в одежду по типу туник, доспехов и т.п. Я набросал на бумагу свое приблизительное видение персонажа и пришел к своей девушке — графическому дизайнеру. Горящий идеей и с кривым рисунком в руках, я попытался объяснить, что прямо сейчас нам необходимо нарисовать коллекцию гоблинов в стиле пиксель-арт.

Предложение увенчалось успехом, и мы приняли решение нарисовать по слоям 5 разных гоблинов, 5 элементов вооружения, 5 элементов одежды и 5 однотонных фонов. Итого 5^4 = 625 уникальных айтемов.

Работа пошла: моя девушка и, по совместительству, единственный партнер по проекту, начала отрисовывать в PS первого персонажа — голенького и пока еще хрупкого, зеленого гоблина.

Я в свою очередь стал изучать массу разнообразных источников, дабы выяснить, что из себя фундаментально представляет NFT, как это сделать и где публиковать.

Стоит отметить, что я не нашел ровным счетом ничего на русскоязычных источниках, кроме самой базовой информации. Поэтому все, что помогло мне в разработке, пришлось брать с множества разных ресурсов: американские тематические форумы, американский ютуб, итальянский ютуб, китайский ютуб и много-много чего еще.

Процесс разработки

Итак, первое, что я выяснил — есть несколько площадок для продажи своих NFT. Самыми популярными являются OpenSea и Rarible. Как понял, OpenSea более доступна, т.к. комиссия за продажу айтемов платится непосредственно в момент продажи, т.е. площадка просто забирает часть суммы с продажи себе. А Rarible — это площадка, которая направлена больше в сторону настоящего искусства, нежели простых сгенерированных пиксель-арт картинок. Исходя из этого, выбор пал на OpenSea.

На OpenSea можно сделать NFT двумя способами:

  1. Нажать на сайте кнопку "Create" и вручную выбрать медиафайл, добавить название, описание и другую информацию описывающую айтем.

  2. Написать собственный смарт-контракт и заминтить айтем(ы).

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

OpenSea на данный момент поддерживает два блокчейна — Ethereum и Polygon. Но Ethereum — это дорого, и чтобы сделать 625 айтемов, по моим рассчетам нужно было заплатить около $16,000 за "газ", а также некоторую сумму, как первоначальный взнос перед листингом первого айтема. С Polygon такой проблемы нет: создание и листинг NFT происходит бесплатно, первоначального взноса нет, но айтемы на Polygon'е нельзя выставлять на аукцион, только фиксированная цена. Это мне подходит :)

Я нашел на ютубе парня — Patrick Collins, который рассказывал о том, как написать смарт-контракт и "за копейки" заминтить свои NFT, используя блокчейн Chainlink (LINK). У него было несколько разных гайдов, например, как сделать NFT с изображением в IPFS в качестве "обложки" или как сделать NFT с base64 SVG в качестве обложки. Позже выяснилось, что парень является основателем Chainlink — топ 20 токен в мире по мнению Coinmarcetcap.

Благодаря Патрику и некоторым другим видео, я выяснил, что смарт-контракт можно написать на языке программирования Solidity, а для его деплоя необходима некая среда. Передо мной встал выбор, с помощью чего деплоить смарт-контракт:

  • Brownie — такой фреймворк для деплоя смарт-контрактов, с написанием кода на Python.

  • Hardhat — тоже фреймворк, но код пишется на JavaScript.

  • Remix — онлайн IDE для написания и деплоя смарт-контрактов.

Как упоминал в начале статьи, я являюсь Frontend-разработчиком, а значит ближе всех мне подходит Hardhat с возможностью написания кода на JavaScript.

Тем временем первый гоблин был отрисован, и более того, к нему был отрисован фон (изначально планировалось рисовать полноценные фоны, но из-за небольшого разрешения 100x100 пикселей, гоблины попросту терялись в деталях фонов).

Первый комплект (зеленый скин, одежда "тряпье", оружие "копье" и фон "таинственный лес")
Первый комплект (зеленый скин, одежда "тряпье", оружие "копье" и фон "таинственный лес")

Прежде, чем писать смарт-контракт, мне нужен был генератор моих "NFT", то есть программа, которая возьмет все отрисованные слои и сгенерирует из них 625 уникальных изображений, а также соберет все в отдельные json'ы. Так выглядит json моих NFT:

{
  "name": "Freaky Goblin #0",
  "description": "blue heavy goblin with spear on pink bg",
  "attributes": [
    {
      "trait_type": "Bg",
      "value": "pink"
    },
    {
      "trait_type": "Goblin",
      "value": "blue"
    },
    {
      "trait_type": "Cloth",
      "value": "heavy"
    },
    {
      "trait_type": "Weapon",
      "value": "spear"
    }
  ],
  "image": "ipfs://QmcNAyfyFC8G9PMMWXNBB1t3RxVp9YscWzLfwCa218CbUR"
}

Это документ, который описывает объект NFT: его имя, описание, атрибуты и изображение.

За основу генератора я взял скрипт на Python, написанный тем самым создателем китов и сильно переписал его под свои нужды: помимо генерации картинок и json'ов, мне также нужно было, чтоб скрипт загружал все эти картинки в Pinata. Pinata — это такой сервис, который загружает ваши данные в IPFS и возвращает хеш, по которому в дальнейшем можно эти данные получить. IPFS — это, очень простым языком, большой и безотказный файлообменник в интернете. Картинки могут храниться в Pinata как угодно, потому что у них будет хеш, который будет указываться в json'е (как видно в листинге выше). А с самими json'ами посложнее: для смарт-контракта нужно указать базовую точку, откуда для каждого токена будет взят json, то есть нужна такая "директория", в которой по номеру будут лежать все json'ы. Что то-вроде goblins/0.json , goblins/1.json и т.д. Поэтому, после генерации гоблинов я складываю все json'ы в отдельную директорию и затем загружаю на Pinata саму директорию, благо сервис позволяет так делать. Теперь получается так, что в файловой системе IPFS лежит директория со всеми json'ами, к которой я могу обратиться, как ipfs_hash/0.json. Отлично!

Когда генератор сделан, все изображения и данные для NFT сгенерированы и загружены — можно писать смарт-контракт. С этой частью я мучался больше всего, пытаясь писать его с помощью всех выше упомянутых вариантов: Brownie, Hardhat и Remix. Но из всего процесса опишу только успешный с помощью Hardhat, дабы избавить вас от ненужных подробностей.

OpenSea предоставляет для разработчиков тестовую среду. Ровно также, как Matic и Ethereum предоставляют тестовые сети. То есть для деплоя нужно просто переключить сеть в кошельке Metamask. Так как я собираюсь деплоить в сети Polygon, мне нужна тестовая сеть Polygon — Mumbai. Добавить ее в кошелек можно здесь. Просто ввести в поиске "Mumbai" и подключить Metamask, все просто. Когда сеть добавлена — можно пополнить баланс кошелька. Также необходимо описать конфиг для Hardhat, чтоб деплоить в нужной сети.

В качестве базы для NFT можно взять уже написанный смарт-контракт OpenSea Creatures. В репозитории можно на выбор найти несколько разных смарт-контрактов (Single, Bundle и т.д.) и по их примеру пробовать писать свои. Но главное — это ERC721Tradable.sol и его зависимости. То есть основной функционал, такой как владение или трансфер уже будет реализован в нем, а нам остается только написать функционал минтинга.

Спустя долгое время изучения Solidity и тестирования смарт-контракта, у меня наконец получилось заминтить полноценную коллекцию в тестовой сети. Я принялся минтить это все в продакшн. Кстати, на минтинг 625 токенов ушло около $60.
И вот, коллекция готова, все 625 токенов отображаются корректно, функционал работает. Последний штрих, чтоб было совсем красиво — верифицировать смарт-контракт. Это делается с помощью того же Hardhat.

К сожалению, на данный момент, OpenSea предоставляет API для листинга токенов только в сети Ethereum, поэтому я написал AppleScript, который автоматизировал работу моего Mac и за ночь залистил все 625 токенов. Также добавил скрипт для обновления метаданных моих NFT — бывает, что метаданные подтягиваются не сразу, и для этого есть кнопка "Refresh Metadata", но можно сделать это и с помощью скрипта.

Завершение

Прошло 4 месяца с момента релиза нашей коллекции и, сказать честно, ни один айтем не продался. За это время я пробовал сбивать цену, всячески продвигать своих гоблинов, даже заказал дискорд сервер у фрилансера. Но кажется, что коллекция попросту оказалась слишком проста и не несла за собой "вау" эффекта.

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

Это было интересно. Наша коллекция — это хоть и безуспешный, но совместный проект, который мы полюбили и довели до конца. Получили хороший экспириенс и собственные NFT.

Репозиторий на GitHub
Сайт коллекции
Коллекция

Я буду только рад, если кто-то, воспользовавшись этим проектом, упростит себе задачу и сделает свою крутую коллекцию, которая выстрелит :)

От вас прошу комментариев, критика тоже приветствуется, я знаю, что ей здесь есть место.




К сожалению, не доступен сервер mySQL