Настройка хранения метаданных NFT на IPFS
IPFS — content-addressed хранилище: адрес файла (CID) это хэш его содержимого. Изменить файл по тому же адресу невозможно — это фундаментальное свойство, которое делает IPFS правильным выбором для NFT метаданных. Если контракт хранит ipfs://QmXxx... в tokenURI — арт и метаданные привязаны к конкретному содержимому навсегда.
Структура метаданных и пиннинг
Что и как загружаем
Стандартный набор для NFT-коллекции:
-
images/— PNG/WebP файлы токенов, 1000x1000px минимум -
metadata/— JSON файлы, по одному на токен - Опционально: анимации (MP4/WebM), 3D модели (GLB)
Каждый JSON метаданных содержит image поле с IPFS URI изображения. Загрузку делаем в два этапа: сначала загружаем папку с изображениями, получаем CID директории, затем генерируем JSON с этим CID в image полях, загружаем JSON-папку. Так IPFS CID метаданных фиксирован и содержит ссылки на фиксированные изображения — полная цепочка immutability.
Пиннинг: почему он критичен
IPFS по умолчанию удаляет файлы через garbage collection, если на них нет active pin. Без пиннинга файлы существуют только пока кто-то активно их запрашивает. Для NFT это неприемлемо.
Pinata — наиболее распространённый сервис. API для программного пиннинга, выделенные gateway URLs, поддержка IPFS + Arweave. Есть бесплатный tier для тестирования.
NFT.Storage (теперь nft.storage/storacha) — бесплатное хранение NFT данных через Filecoin. Надёжное долгосрочное хранение, но менее гибко в API.
Web3.Storage — Filecoin-backed хранение с HTTP gateway. Альтернатива для тех, кто хочет redundancy через Filecoin deals.
Для серьёзных коллекций рекомендуем double-pin: Pinata + Arweave. Arweave — permanent storage с одноразовой оплатой, данные хранятся навсегда через endowment механизм. Стоимость — ~$5-15 за GB. Для коллекции на 10 000 токенов с 5 MB изображениями — ~$300 за вечное хранение.
Практическая настройка
Скрипт загрузки через Pinata API (Node.js):
import { PinataSDK } from "pinata";
const pinata = new PinataSDK({ pinataJwt: process.env.PINATA_JWT });
// Upload images folder
const imagesUpload = await pinata.upload.folder("./images");
const imagesCID = imagesUpload.IpfsHash;
// Generate and upload metadata
const metadata = tokens.map((id) => ({
name: `Collection #${id}`,
image: `ipfs://${imagesCID}/${id}.png`,
attributes: traits[id]
}));
const metaUpload = await pinata.upload.folder(metadata, { name: "metadata" });
CID из metaUpload.IpfsHash — это то, что идёт в baseURI контракта.
Проверка доступности
После загрузки проверяем доступность через публичные IPFS gateway (cloudflare-ipfs.com, ipfs.io). Важно: не захардкоживать в контракте конкретный gateway — только ipfs://CID/. Маркетплейсы (OpenSea, Blur) сами резолвят IPFS URI через свои gateway.
Ориентиры по срокам
Настройка пиннинга и загрузка метаданных для готовой коллекции — 1 рабочий день. Включает: upload изображений, генерацию JSON, пиннинг на Pinata + резервный Arweave, проверку доступности через gateway, передачу CID для контракта.







