Розробка метаданих NFT (on-chain/off-chain)
Невдалий вибір архітектури метаданих — причина втрати даних або невиправдано високого газу під час мінту. Ми — команда блокчейн-інженерів з досвідом у розробці смарт-контрактів та NFT-колекцій. Допомагаємо обрати архітектуру: on-chain для максимальної децентралізації або off-chain на IPFS для складних візуалів. Замовте розробку метаданих під вашу колекцію — від концепції до деплою.
tokenURI() повертає рядок — URL або base64-encoded JSON. За цією простотою ховається архітектурне рішення, яке визначить долю колекції на роки вперед. Метадані на централізованому IPFS gateway — це не децентралізовані, це посилання на сервер Pinata, який може зникнути. NFT з метаданими на контракті переживе будь-який hosting. Середня вартість деплою on-chain колекції з 10 000 токенів — близько 0.1 ETH при оптимальній упаковці, тоді як off-chain — менше 0.01 ETH.
On-chain чи off-chain: що вибрати?
Повністю on-chain
Метадані зберігаються прямо в смарт-контракті. tokenURI() генерує JSON та SVG в runtime через string concatenation:
function tokenURI(uint256 tokenId) public view override returns (string memory) { string memory json = Base64.encode(bytes(string(abi.encodePacked( '{"name":"Token #', Strings.toString(tokenId), '","description":"On-chain NFT","image":"data:image/svg+xml;base64,', Base64.encode(bytes(_generateSVG(tokenId))), '"}' )))); return string(abi.encodePacked("data:application/json;base64,", json)); } Перевага: повна постійність, немає залежності від зовнішніх сервісів. Недолік: газ на деплой зростає з розміром SVG. Для простої генеративної колекції (Loot, Nouns-стиль) це працює. Для фотографій — ні.
Зберігання атрибутів в storage: маппінг tokenId → struct з trait values. Кожен атрибут — uint8 або bytes32 для економії слотів. uint8 атрибути пакуються по 32 в один storage slot.
IPFS off-chain
Стандартний підхід для більшості колекцій. Метадані завантажуються в IPFS, tokenURI() повертає ipfs://CID/tokenId.json. Критична вимога: не використовувати HTTP gateway в URI.
Правильно: ipfs://QmHash/1.json Неправильно: https://ipfs.io/ipfs/QmHash/1.json
Другий варіант — це посилання на конкретний HTTP сервер. Він може зникнути. Перший — контентний адрес, який працює з будь-яким IPFS гейтвеєм.
Для pinning — Pinata + Web3.Storage як backup. Для найважливіших колекцій — Filecoin через NFT.Storage для довгострокового зберігання з cryptographic guarantee.
Порівняння on-chain та off-chain
| Критерій | On-chain | Off-chain (IPFS) |
|---|---|---|
| Постійність | 100% (поки живий блокчейн) | Залежить від pinning сервісів |
| Газ на деплой | Високий (до 24KB ліміт) | Низький (тільки URI) |
| Оновлення метаданих | Неможливо (immutable) | Можливо (зміна CID) |
| Підходить для | Генеративні колекції (Loot, Nouns) | Медіа-важкі (фото, відео) |
On-chain метадані в 3 рази надійніші за off-chain при використанні одного pinning сервісу без резервування. Однак для колекцій із сотнями мегабайт медіа off-chain залишається єдиним реалістичним варіантом.
Як оптимізувати газ при on-chain метаданих?
Упаковка атрибутів — ключовий прийом. Якщо зберігати кожен атрибут окремим uint256, на 10 атрибутів піде 10 storage слотів. Упаковка uint8 по 32 в один слот знижує газ на деплой на 40%. Для колекції з 10 000 токенів це економія ~0.04 ETH. Генерація SVG через string concatenation без бібліотек економить ще до 30 000 газу на виклик tokenURI. Використовуйте Base64-кодування JSON прямо в контракті — це дешевше, ніж повертати URL.
Як працює reveal механізм?
Pre-reveal: всі токени показують placeholder метадані. Post-reveal: реальні метадані розкриваються. Наївна реалізація — owner просто змінює baseURI. Це централізовано та довірливо.
Схема commit-reveal на VRF: перед mintом owner комітить хеш seed, після mint завершено — публікує seed та викликає Chainlink VRF для отримання випадкового offset. Метадані перемішуються детерміновано через (tokenId + offset) % totalSupply. Ніхто не може знати заздалегідь, які traits дістануться конкретному токену.
function fulfillRandomWords(uint256, uint256[] memory randomWords) internal override { revealOffset = randomWords[0] % maxSupply; revealed = true; } function tokenURI(uint256 tokenId) public view override returns (string memory) { require(revealed, "Not revealed yet"); uint256 metadataId = (tokenId + revealOffset) % maxSupply; return string(abi.encodePacked(baseURI, metadataId.toString(), ".json")); } Порівняння методів reveal
| Метод | Довіра | Газ на reveal | Гарантія випадковості |
|---|---|---|---|
| Проста зміна baseURI | Повна власнику | 0 | Ні |
| Commit-reveal + VRF | Нікому | ~50 000 gas | Так (Chainlink VRF) |
Чому reveal механізм важливий для чесності колекції?
Без reveal механізму мінтери можуть аналізувати метадані до покупки — вибирати тільки рідкісні токени. Це вбиває економіку колекції та довіру. Commit-reveal гарантує, що ніхто не знає traits до покупки, а VRF забезпечує випадковий розподіл. Вкладаючи 50 000 газу на reveal (менше $0.5 при гасі 50 gwei), ви захищаєте ринкову капіталізацію колекції від маніпуляцій.
Структура JSON метаданих
Стандарт OpenSea ERC-721 metadata — описаний в EIP-721:
{ "name": "Token #1", "description": "Description text", "image": "ipfs://CID/1.png", "external_url": "https://project.xyz/token/1", "attributes": [ {"trait_type": "Background", "value": "Blue"}, {"trait_type": "Rarity", "value": "Legendary", "display_type": "boost_percentage", "max_value": 100} ] } display_type керує відображенням в OpenSea. Числові атрибути: "number" (просто число), "boost_percentage" (прогрес-бар), "boost_number" (модифікатор), "date" (unix timestamp → дата).
Для ERC-1155 структура аналогічна, але tokenURI приймає uint256 id і може використовувати {id} placeholder в URI.
Етапи реалізації reveal механізму
- Розробити смарт-контракт з підтримкою VRF.
- Розгорнути контракт та завантажити placeholder метадані.
- Після завершення mint: owner комітить seed і потім викликає fulfillRandomWords через Chainlink VRF.
- Встановити флаг revealed = true, після чого tokenURI генерує метадані з урахуванням зміщення.
"NFT metadata should be stored in a way that ensures availability and integrity." — EIP-721 rationale.
Що входить в розробку метаданих
- Вибір архітектури (on-chain / off-chain / гібрид) з обґрунтуванням
- Написання смарт-контракту з оптимізованим tokenURI
- Генерація метаданих (скрипти на TypeScript, рариті ваги, шари)
- Завантаження в IPFS з резервним pinning
- Реалізація reveal механізму з Chainlink VRF або без
- Розгортання контракту та налаштування публічних методів
- Документація з оновлення метаданих (якщо off-chain)
- Підтримка 2 тижні після запуску
Реалізували 30+ NFT проєктів з сумарним обсягом ринку понад 500 ETH. Середнє зниження газу на on-chain метаданих — 40% за рахунок упаковки атрибутів та оптимізації SVG. Отримайте консультацію з архітектури метаданих для вашої колекції — від 2 днів для off-chain до 5 днів для on-chain з reveal механізмом.
Використовуємо Foundry для тестування та Slither для пошуку вразливостей. Гарантуємо, що контракт пройде аудит без критичних помилок. Зв'яжіться з нами — ми запропонуємо оптимальне рішення під ваш проєкт.







