Розробка PFP NFT-колекції
PFP (Profile Picture) колекція — 10 000 унікальних зображень, згенерованих з trait шарів: фон, тіло, одяг, голова, аксесуари. Технічно це конкретний пайплайн: генератор зображень + алгоритм розподілу рарити + ERC-721 контракт з reveal механікою + IPFS-хостинг метаданих. Задача не в тому, щоб "зробити NFT" — задача в тому, щоб зробити правильно з точки зору безпеки мінтингу та честного розподілу рарити.
Де ломаються PFP-проекти
Передбачуваний rarity reveal
Найпоширеніша помилка: метаданні розкриваються одразу при мінтингу. Холдер токену отримує #4521, йде на rarity.tools — бачить, що це топ-1% по редкості. Досвідчені гравці скануються транзакції в реальному часі й front-run мінтинг рідких токенів, передбачаючи token ID за порядком транзакції.
Рішення — delayed reveal: усі токени показують placeholder при мінтингу. Після закінчення мінту — reveal, власник проекту встановлює 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 через маппінг — базова захист. Обходиться через контракти, якщо не додати
require(tx.origin == msg.sender)або ERC-721Psi з packed ownership.
Як ми будуємо колекцію
Генератор зображень
Python-скрипт на базі Pillow: завантажує PNG шари з прозорістю, компонує за пріоритетом, зберігає итогове зображення. Конфіг для кожного trait: {name, weight, files[]}. Генератор гарантує унікальність через hash згенерованих комбінацій, при колізії повторює генерацію.
Фінальний крок — validation скрипт: перевіряє відсутність дубліків, відповідність ваг ожидаємому розподілу рарити (±2%), коректність усіх файлів метаданих.
ERC-721 контракт
Базується на ERC-721A (від Azuki) — оптимізована реалізація, яка дозволяє мінтити кілька токенів за одну транзакцію з майже тією ж ціною газу, що й один токен. Оригінальний OpenZeppelin ERC-721 оновлює _owners маппінг для кожного tokenId — це O(n) по газу при мінтингу n токенів. ERC-721A використовує lazy initialization: _owners оновлюється тільки для першого токену в batch.
Економія суттєва: мінтинг 5 ERC-721A токенів коштує ~120k газу проти ~400k для стандартного ERC-721. На mainnet при 50 gwei це різниця $20 vs $66 за транзакцію.
Додаткові компоненти: EIP-2981 для роялті (підтримується OpenSea, Blur, LooksRare), Ownable2Step замість Ownable (захист від випадкової передачі прав), ERC721Burnable якщо планується механіка сжигання.
Зберігання метаданих
IPFS через Pinata або NFT.Storage. Структура: всі зображення завантажуються в один IPFS директорій, отримуємо 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 шари з прозорістю, конфіг ваг traits. Генеруємо превью вибірки з 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 (опис, роялті, баннер).
Кошторис по часу
Від отримання арт-файлів до деплою на mainnet — 1.5–2 тижні. Окремі механіки (staking, merging токенів, on-chain генерація) додають 1–2 тижні кожна.







