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 и др.).