IPFS: где хранить картинки и метаданные

Картинки и метаданные дорого хранить on-chain. IPFS — децентрализованное хранилище для тяжёлых файлов dApp.

IPFS — распределённая файловая сеть с адресацией по содержимому: файл идентифицируется его хешем (CID), а не путём. Один и тот же файл всегда имеет один и тот же CID.

Хранить картинку в блокчейне — безумно дорого (каждый байт стоит газ). Поэтому тяжёлые данные (изображения NFT, JSON-метаданные, документы) держат вне сети, а в контракте — только ссылку. Классическое решение — IPFS.

Адресация по содержимому

В обычном вебе ссылка указывает на место (example.com/img.png) — поменяли файл, ссылка та же, содержимое другое. В IPFS ссылка указывает на содержимое: CID — это хеш файла. Изменился файл — изменился CID. Это даёт неизменяемость: ссылка ipfs://bafy... всегда вернёт ровно тот файл, что и был. Для NFT это важно — нельзя втихую подменить картинку.

ipfs://bafybeigdyr…   <-- CID (хеш содержимого)
        |
   тот же CID всегда = тот же файл, где бы он ни хранился

Шлюзы: мост в обычный веб

Браузер не говорит на протоколе IPFS. Чтобы показать файл, используют шлюз — HTTP-сервер, отдающий контент по CID:

ipfs://bafy.../1.png
  --> https://ipfs.io/ipfs/bafy.../1.png       (публичный шлюз)
  --> https://CID.ipfs.dweb.link/1.png          (subdomain-шлюз)
  --> https://gateway.pinata.cloud/ipfs/bafy... (свой шлюз провайдера)

Пиннинг: чтобы файл не исчез

Важная тонкость: IPFS не гарантирует вечного хранения. Файл живёт, пока хотя бы один узел его «пиннит» (держит). Если все узлы его выкинут — файл пропадёт, и NFT покажет битую картинку. Поэтому используют пиннинг-сервисы (Pinata, web3.storage, Filecoin) — они гарантируют, что файл закреплён и доступен.

Как работает под капотом

Когда вы загружаете файл в IPFS, он разбивается на блоки, каждый хешируется, из хешей строится дерево, а корневой хеш и есть CID. Любой узел сети, у которого есть эти блоки, может отдать файл по CID — поэтому адресация «по содержимому, а не по серверу». Загрузка обычно идёт через API пиннинг-сервиса (он возвращает CID), а чтение — через шлюз. Для фронта это выглядит как «загрузил → получил CID → положил ipfs://CID в метаданные/контракт».

Частые ошибки

  • Думать, что IPFS = вечное хранилище. Без пиннинга файл может исчезнуть; используйте пиннинг-сервис.
  • Завязываться на один публичный шлюз. Он может тормозить или лежать; имейте запасной.
  • Хранить приватные данные в IPFS. Контент публичен по CID; шифруйте чувствительное.

Итоги

  • IPFS хранит тяжёлые файлы dApp; в контракте — только ссылка (CID).
  • CID — хеш содержимого: неизменяемость и одинаковая ссылка на одинаковый файл.
  • Браузеру нужен шлюз; для надёжности файлы пиннят (Pinata и др.).
Проверьте себя
1. Что такое CID в IPFS?
AАдрес сервера
BХеш содержимого файла — идентификатор по содержимому
CПриватный ключ
DНомер блока
2. Почему файл в IPFS может исчезнуть?
AIPFS платный по времени
BЕсли ни один узел его не пиннит (не держит)
CПосле каждого блока
DИз-за смены chainId
3. Зачем нужен IPFS-шлюз?
AЧтобы подписывать транзакции
BЧтобы браузер мог получить файл по HTTP, не понимая протокол ipfs://
CЧтобы платить газ
DЧтобы сменить сеть