Розробка метаданих NFT (on-chain/off-chain)

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка метаданих NFT (on-chain/off-chain)
Простий
~2-3 дні
Часті запитання

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

Етапи блокчейн-розробки

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

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

Розробка метаданих NFT (on-chain/off-chain)

tokenURI() повертає рядок — URL або base64-encoded JSON. За цією простотою скривається архітектурне рішення, яке визначить долю колекції на роки вперед. Метаданні на централізованому IPFS gateway — це не «децентралізовані метаданні», це посилання на сервер Pinata, який може зникнути. NFT з метаданнями на контракті (on-chain) переживе будь-яке hosting.

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. Для простої generative коллекції (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 gateway.

Для пиннінгу — Pinata + Web3.Storage як backup. Для найважливіших коллекцій — Filecoin через NFT.Storage для довгострокового зберігання з криптографічною гарантією.

Механізм 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"));
}

Структура JSON метаданих

OpenSea ERC-721 metadata стандарт:

{
  "name": "Token #1",
  "description": "Текст опису",
  "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.

Інструменти й процес

Генерація метаданих для великої коллекції — off-chain TypeScript скрипт: загружає layers, генерує комбінації з урахуванням рарити weights, створює JSON файли та зображення, batch загружає в IPFS через Pinata API. Потім IPFS CID фіксується в контракті.

Для on-chain SVG — TypeScript скрипт генерує Solidity бібліотеки зі string констант для кожного trait. Розмір контракту перевіряється: ліміт 24KB.

Ориєнтири по термінах

IPFS off-chain метаданні з reveal механізмом — 2-3 дні. On-chain SVG генерація для generative коллекції — 3-5 днів залежно від складності арту.