После запуска PFP-проекта Bored Ape Yacht Club десятки команд скопировали механику, но большинство провалилось на технической реализации: переполнение газа при минте, украденные редкие токены, прозрачный reveal. Проблема не в арте — в коде. Мы разрабатываем PFP NFT-коллекции от генерации слоёв до деплоя смарт-контракта на mainnet. Стандартный проект — 10 000 уникальных изображений с честным распределением рарити и защитой от MEV-ботов. Свяжитесь с нами для консультации по вашему проекту и получите полный пайплайн.
Почему PFP-проекты ломаются?
Предсказуемый rarity reveal. Самая распространённая ошибка: метаданные открываются сразу при минте. Пользователь получает #4521, идёт на rarity.tools — видит, что это топ-1% по редкости. Опытные игроки сканируют транзакции в реальном времени и front-run минт редких токенов, предугадывая token ID по порядковому номеру транзакции.
Решение — delayed reveal: при минте все токены показывают placeholder изображение. После окончания минта владелец проекта устанавливает baseURI с реальными метаданными через setBaseURI. Но это порождает другую проблему: команда знает финальный mapping tokenId → trait заранее и может зарезервировать редкие токены.
Честный reveal — через Chainlink VRF. После окончания минта запрашиваем случайное число у VRF, используем его как offset: tokenId #5000 получает метаданные из файла (5000 + offset) % totalSupply. Ни команда, ни минтеры не знают финальный mapping до получения randomness.
Неравномерное распределение при генерации. Наивный генератор выбирает каждый trait случайно с весами — но не проверяет комбинации. В результате «редкий» trait может случайно встречаться чаще ожидаемого из-за корреляции с популярными базовыми traits. Правильный подход: задаём точное количество каждого trait, генератор shuffle'ит и распределяет детерминированно, проверяет итоговую rarity таблицу перед финализацией.
Как защитить минт от ботов?
Без защиты первые 1000 токенов уходят MEV-ботам за один блок. Стандартные механизмы:
- Merkle proof whitelist: только адреса из списка могут минтить.
MerkleProof.verifyиз OpenZeppelin — дёшево по газу. - Commit-reveal: пользователь сначала фиксирует намерение минта (commit), через N блоков забирает токен (reveal). Предотвращает atomic snipe ботов.
- Max per wallet через mapping — базовая защита. Обходится через контракты, если не добавить
require(tx.origin == msg.sender)или ERC-721Psi с packed ownership.
Как мы строим PFP NFT-коллекцию: пошагово
-
Генератор изображений. Python-скрипт на базе Pillow: загружает слои PNG с прозрачностью, компонует по приоритету, сохраняет итоговое изображение. Конфиг для каждого trait:
{name, weight, files[]}. Генератор гарантирует уникальность через hash сгенерированных комбинаций, при коллизии повторяет генерацию.Финальный шаг — validation скрипт: проверяет отсутствие дубликатов, соответствие весов ожидаемому распределению рарити (±2%), корректность всех файлов метаданных.
-
ERC-721 контракт. Базируемся на ERC-721A (от Azuki) — оптимизированная реализация, которая позволяет минтить несколько токенов за одну транзакцию с почти той же ценой газа, что и один токен. Оригинальный OpenZeppelin ERC-721 обновляет
_ownersmapping для каждого tokenId — это O(n) по газу при минте n токенов. ERC-721A использует lazy initialization:_ownersобновляется только для первого токена в batch.Параметр OpenZeppelin ERC-721 ERC-721A Gas за 1 токен ~80k gas ~80k gas Gas за 5 токенов ~400k gas ~120k gas Initialization mapping На каждый tokenId Ленивая, только первый Экономия существенная: на mainnet при 50 gwei это разница $66 vs $20 за транзакцию. Дополнительные компоненты: EIP-2981 для роялти,
Ownable2StepвместоOwnable(защита от случайной передачи прав),ERC721Burnableесли планируется сжигание.Хранение метаданных. IPFS через Pinata или NFT.Storage. Структура: все изображения загружаются в одну директорию, получаем CID. Метаданные JSON ссылаются на
ipfs://{CID}/{tokenId}.png.baseURIв контракте —ipfs://{CID}/. Формат метаданных по стандарту OpenSea:{ "name": "Collection #1234", "description": "...", "image": "ipfs://Qm.../1234.png", "attributes": [ {"trait_type": "Background", "value": "Blue"}, {"trait_type": "Eyes", "value": "Laser"} ] }trait_typeиvalueдолжны точно совпадать с rarity таблицей — от этого зависит корректность отображения на OpenSea и rarity агрегаторах.Процесс работы
- Арт и слои (параллельно с разработкой). Принимаем от клиента: PNG слои с прозрачностью, конфиг весов trait'ов. Генерируем превью выборки из 100 токенов для согласования.
- Генератор и rarity (2-3 дня). Финальная генерация 10K изображений, rarity таблица, валидация уникальности.
- Загрузка на IPFS (1 день). Загрузка через Pinata API, получение CID.
- Контракт и тесты (3-4 дня). ERC-721A + VRF reveal + whitelist. Foundry тесты: минт, reveal, transfer, royalty.
- Деплой (1-2 дня). Testnet (Sepolia) → согласование → mainnet. Верификация на Etherscan. Настройка коллекции на OpenSea (description, royalties, banner).
Сравнение методов защиты от ботов
Метод Сложность реализации Риск обхода Газовые затраты Merkle whitelist Низкая Низкий (при правильном mapping) Низкие Commit-reveal Средняя Средний (front-running не устраняется полностью) Средние Max per wallet (tx.origin) Низкая Высокий (контракт-прокси) Низкие ERC-721Psi Средняя Низкий Очень низкие Что входит в работу (deliverables)
- Полный исходный код генератора, контракта, тестов и скриптов развёртывания.
- Документация настройки коллекции на маркетплейсах.
- Доступ к Pinata аккаунту с загруженными метаданными.
- Онлайн-метрика распределения рарити после reveal.
- Поддержка после деплоя — 2 недели (консультации, исправления).
Сроки и стоимость
От получения арт-файлов до деплоя на mainnet — 1.5-2 недели. Стоимость рассчитывается индивидуально в зависимости от сложности и количества слоёв. Наши инженеры имеют более 5 лет опыта в смарт-контрактах и 20+ реализованных PFP-проектов. Закажите разработку PFP-коллекции — получите полный пайплайн с защитой от ботов и честным reveal.







