Что такое IPFS и зачем он в Web3
IPFS в Web3: что такое CID, почему NFT хранят metadata вне Ethereum и как читать ipfs:// ссылки через gateway.
Что такое IPFS
IPFS — это сеть для хранения файлов по их содержимому, а не по адресу сервера.
В обычном Web файл лежит по URL: https://example.com/image.png. В IPFS файл лежит по CID — хешу содержимого: ipfs://bafy....
Почему это важно для Web3
Ethereum хорошо хранит маленькие данные: балансы, адреса, числа, состояния контрактов.
Большие файлы хранить в Ethereum дорого:
NFT metadata JSON
картинка
видео
документ
архивПоэтому контракт часто хранит только ссылку:
tokenURI = ipfs://bafy.../123.jsonА сам JSON и медиафайлы лежат в IPFS.
CID вместо URL
CID — это Content Identifier. Он зависит от содержимого файла.
Если файл изменился, CID тоже изменится:
metadata.json → ipfs://CID_A
metadata изменили → ipfs://CID_BЭто главное отличие от обычного URL. Владелец сервера может заменить файл по тому же URL, а CID указывает на конкретное содержимое.
Читаем IPFS-файл через gateway
const ipfsUri = "ipfs://bafkreihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku";
function ipfsToGatewayUrl(uri: string): string {
if (!uri.startsWith("ipfs://")) {
throw new Error("Ожидался ipfs:// URI");
}
const path = uri.replace("ipfs://", "");
return `https://ipfs.io/ipfs/${path}`;
}
const gatewayUrl = ipfsToGatewayUrl(ipfsUri);
const response = await fetch(gatewayUrl);
if (!response.ok) {
throw new Error(`IPFS gateway вернул ${response.status}`);
}
const content = await response.text();
console.log("Gateway URL:", gatewayUrl);
console.log("Content:", content);Этот код берёт ipfs:// ссылку, превращает её в обычный HTTPS URL через public gateway и читает файл.
Как это работает
ipfsUri — ссылка на файл в IPFS. Она не указывает на конкретный сервер.
ipfsToGatewayUrl() — переводит ipfs://CID в https://ipfs.io/ipfs/CID, чтобы файл можно было открыть через обычный HTTP-запрос.
fetch(gatewayUrl) — запрашивает файл через gateway. Gateway находит содержимое в IPFS и отдаёт его как обычный web-сервер.
response.text() — читает содержимое файла. Для NFT metadata вместо этого часто используют response.json().
Как NFT использует IPFS
NFT-контракт обычно хранит tokenURI.
tokenId: 123
tokenURI: ipfs://bafy.../123.jsonВнутри JSON лежит metadata:
{
"name": "Example NFT #123",
"description": "Описание токена",
"image": "ipfs://bafy.../image.png"
}Контракт хранит ownership и правила передачи токена. IPFS хранит metadata и медиафайлы.
IPFS не гарантирует вечное хранение
CID доказывает, что вы получили именно нужный файл. Но он не гарантирует, что кто-то продолжает хранить этот файл.
Чтобы файл был доступен, его должна хранить хотя бы одна IPFS-нода или pinning-сервис:
загрузили файл
↓
получили CID
↓
закрепили файл через pinning
↓
записали ipfs://CID в контракт или metadataБез pinning файл может стать недоступным, даже если CID остался правильным.
IPFS vs Ethereum State
| Что | Где хранить |
|---|---|
| Баланс токена | Ethereum State |
| Владелец NFT | Ethereum State |
| Ссылка на metadata | Ethereum State или событие |
| JSON metadata | IPFS |
| Картинка или видео | IPFS |
Ethereum отвечает за правила и владение. IPFS отвечает за файлы.
Частые ошибки
Думать, что IPFS хранит файл навсегда → CID постоянный, но доступность зависит от pinning.
Хранить только gateway URL → лучше хранить ipfs://CID, а gateway выбирать на стороне приложения.
Считать IPFS приватным хранилищем → если файл доступен по CID, его может прочитать любой, у кого есть этот CID.
Что дальше
- Что такое ABI — как прочитать
tokenURI()из NFT-контракта - Events и логи — как индексаторы находят изменения metadata и ownership
- Чтение данных из контракта — как читать onchain-ссылки через
viewфункции