Full-cycle разработка генеративной 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 недели. Стоимость рассчитывается индивидуально в зависимости от механик минта и требований к фронтенду. Получите консультацию по вашей коллекции — мы поможем подобрать оптимальные механики минта и рассчитаем бюджет. Свяжитесь с нами для обсуждения вашего проекта.