Повний цикл розробки генеративної NFT-колекції: шари, контракти та мінт

10 000 унікальних CryptoPunks, 8 888 Azuki, 8 000 Milady — всі ці колекції побудовані на одному принципі: алгоритмічна комбінація шарів трейтів із заданими ймовірностями народжує унікальні зображення. Технічна сторона складається з двох рівно важливих частин: генератор зображень і смарт-контракт мін

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1267
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1003

10 000 унікальних CryptoPunks, 8 888 Azuki, 8 000 Milady — всі ці колекції побудовані на одному принципі: алгоритмічна комбінація шарів трейтів із заданими ймовірностями народжує унікальні зображення. Технічна сторона складається з двох рівно важливих частин: генератор зображень і смарт-контракт мінту. Помилки на будь-якому етапі — від неправильної матриці сумісності до вразливості в контракті — можуть коштувати тисяч доларів газу та репутації.

У цьому огляді йтиметься про розробку Ethereum колекції: мінтинг NFT, ERC-721A, conditional traits, Merkle tree whitelist, Dutch auction та IPFS метадані. Наша команда займається розробкою NFT-колекцій більше 4 років. За цей час ми випустили понад 10 проектів на Ethereum, Polygon та Solana. Досвід дозволяє гарантувати якість на кожному етапі: від генерації до деплою. У цій статті детально розберемо технічні аспекти створення генеративної колекції: від генерації зображень до деплою смарт-контракту. Ви дізнаєтеся, як уникнути типових помилок та заощадити на газі при batch mint.

Структура трейтів і раритет

Колекція розбивається на шари (background, body, clothing, eyes, mouth, accessories). Кожен шар містить варіанти із заданими вагами. Наприклад, для background:

"background": [ { "name": "Золотий", "weight": 2 }, { "name": "Синій", "weight": 25 }, { "name": "Сірий", "weight": 73 } ] 

Генератор випадково обирає варіант пропорційно вагам і комбінує PNG-шари. Результат: 2% колекції отримують золотий фон, 73% — сірий.

Ключова проблема: при наївній реалізації раритет порушується через конфліктуючі трейти (наприклад, скелет-персонаж не може носити звичайний одяг). Реалізуємо conditional traits: матриця сумісності шарів, яка виключає невалідні комбінації. При великій кількості обмежень алгоритм може зациклитися — потрібен backtracking з max-attempts.

Докладніше про conditional traits Матриця сумісності задається як бітова маска: для кожного шару перелічені дозволені ідентифікатори інших шарів. Генератор на Node.js послідовно обирає варіант кожного шару, перевіряючи сумісність з вже обраними. Якщо зациклення — збільшуємо max-attempts або перезапускаємо генерацію з іншого шару.

Інструмент: власний генератор на Node.js з використанням sharp для compositing PNG-шарів. sharp в 3–5 разів швидше за canvas-based рішення — 10k зображень генеруються за 5–15 хвилин. Для анімованих колекцій (GIF/APNG) — ffmpeg через child process.

Metadata та стандарти

Кожен токен потребує JSON метаданих формату OpenSea metadata standard:

{ "name": "Collection #1234", "description": "...", "image": "ipfs://Qm.../1234.png", "attributes": [ { "trait_type": "Background", "value": "Золотий" }, { "trait_type": "Eyes", "value": "Лазерні" } ] } 

Поле image має вказувати на IPFS або Arweave. Централізований сервер — смерть колекції при закритті. Завантажуємо через Pinata або NFT.Storage, отримуємо CID, формуємо baseURI виду ipfs://QmXxx/. Всі метадані на IPFS завантажуються автоматично.

Смарт-контракт: ERC-721 та механіки мінту

Чому варто використовувати ERC-721A?

Базова структура на OpenZeppelin:

contract MyCollection is ERC721A, Ownable, ReentrancyGuard { uint256 public constant MAX_SUPPLY = 10000; uint256 public constant MAX_PER_WALLET = 5; string private _baseTokenURI; mapping(address => uint256) public mintedPerWallet; } 

Використовуємо ERC-721A (Azuki's implementation) замість стандартного ERC-721: batch mint 5 токенів в ERC-721A споживає ~50k газу проти ~250k в класичній реалізації. Різниця відчутна при 10k колекції на Ethereum mainnet. Економія газу сягає 80% при масовому мінті.

Метрика ERC-721 (OpenZeppelin) ERC-721A (Azuki)
Газ на mint 1 токена ~90k ~50k
Газ на mint 5 токенів ~250k ~50k
Підтримка burn Так Так
Аудит Багато аудитів Аудовано (Azuki)

Механіки мінту

Public mint — відкритий для всіх, часто з обмеженням per wallet. Захист: require(mintedPerWallet[msg.sender] + quantity <= MAX_PER_WALLET). Проблема з контрактами: msg.sender — контракт, обходить ліміт. Додаємо require(msg.sender == tx.origin) — але це ламає Safe/AA wallets. Компроміс: перевірка msg.sender == tx.origin лише в період mint, знімається після.

Whitelist mint — Merkle tree proof. Список адрес → корінь Merkle tree → root зберігається в контракті. Користувач надає proof (масив хешів), контракт верифікує через MerkleProof.verify() з OpenZeppelin. Proof генерується off-chain через merkletreejs, публікується на фронтенді.

Dutch auction mint — ціна починається високою і падає кожні N хвилин до мінімуму. Поточну ціну рахуємо через startPrice - (elapsedTime / step) * priceDecrement. Користувач платить поточну ціну, надлишок ETH повертається в тій же транзакції.

Механіка Доступ Ціна Gas cost Складність реалізації
Public mint Всі Фіксована Низька Низька
Whitelist mint За списком Фіксована або знижка Середня Середня
Dutch auction Всі Динамічна (спадна) Середня Висока

Як захистити колекцію від снайперів?

Reveal механіка — преміальні колекції не розкривають трейти до закінчення продажу (anti-snipe). До reveal: tokenURI() повертає один спільний placeholder. Після reveal: owner викликає setBaseURI(ipfsCID) і всі токени миттєво показують фінальні зображення.

Більш чесна механіка: Chainlink VRF для випадкового seed. Контракт запитує random через requestRandomWords(), отримує відповідь у fulfillRandomWords(), записує seed. Всі tokenId випадково перемішуються відносно seed — не можна вгадати трейти навіть знаючи порядок мінту.

Royalties та маркетплейси

ERC-2981 — стандарт on-chain royalties. Маркетплейси, що підтримують стандарт (Blur при включеній опції, OpenSea, Rarible), автоматично читають royaltyInfo(tokenId, salePrice) і утримують відсоток. Додається через ERC2981 mixin з OpenZeppelin.

Для примусового застосування роялті: OperatorFilterRegistry (Blur/OpenSea підхід) блокує трансфери через контракти маркетплейсів, які не дотримуються royalties. Але це спірна механіка — обмежує ліквідність. Рішення: змінний флаг royaltiesEnforced, який owner може вимкнути.

Процес розробки: покроково

  1. Підготовка асетів — шари в PNG з прозорістю, таблиця раритету, матриця несумісностей. Залежить від художника.
  2. Генератор і metadata (2–4 дні) — Node.js генератор, batch генерація колекції, JSON metadata, завантаження на IPFS через Pinata API.
  3. Смарт-контракт (3–5 днів) — ERC-721A базис, механіки мінту (public + whitelist + dutch auction в залежності від вимог), тести в Foundry: supply limits, per-wallet limits, Merkle proof, refund при dutch auction.
  4. Frontend мінт-сайт (3–5 днів) — React + wagmi + viem, підключення MetaMask/WalletConnect, wallet connect, раритет трекер.
  5. Деплой — Testnet (Sepolia) → mainnet. Верифікація контракту на Etherscan.

Вибір механіки мінту

Для економії газу та простоти — public mint з ERC-721A. Якщо важливі контроль доступу та преміальні сценарії — комбінація whitelist + dutch auction. Ми допомагаємо підібрати оптимальний варіант під вашу колекцію та цільову аудиторію.

Що входить в розробку під ключ

  • Вихідний код генератора зображень з конфігурацією трейтів
  • Смарт-контракти з обраними механіками мінту (протестовані на testnet)
  • Метадані всіх токенів (завантажені на IPFS/Arweave)
  • Фронтенд мінт-сайту з підключенням гаманців
  • Документація з управління колекцією (reveal, перевірка контракту)
  • Підтримка при деплої на mainnet

Повний цикл від готових асетів до деплою на mainnet займає 1.5–2 тижні. Вартість розраховується індивідуально в залежності від механік мінту та вимог до фронтенду. Отримайте консультацію по вашій колекції — ми допоможемо підібрати оптимальні механіки мінту та розрахуємо бюджет. Зв'яжіться з нами для обговорення вашого проекту.