Разработка IPFS-инфраструктуры

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Разработка IPFS-инфраструктуры
Средний
~3-5 дней
Часто задаваемые вопросы

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

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

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1308
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1220
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    921
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1149
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    611
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    886

Разработка IPFS-инфраструктуры

IPFS в продакшне отличается от IPFS в туториале примерно так же, как работающий сервер отличается от npm start. Основная проблема — content addressing гарантирует, что данные не изменятся, но не гарантирует доступность. Если нода, которая пинит ваш CID, упадёт — данные недоступны. Для NFT метаданных, которые должны жить вечно, это неприемлемо.

Архитектура: что реально нужно

┌─────────────────────────────────────────────────────┐
│                  Your Application                    │
│                                                      │
│  Upload: File → IPFS Node → CID → Smart Contract    │
│  Fetch:  CID  → IPFS Gateway → File                 │
└───────────────────┬─────────────────────────────────┘
                    │
        ┌───────────┼───────────┐
        ▼           ▼           ▼
   Your IPFS    Pinata /    Cloudflare
     Node      Web3.Storage   IPFS GW
   (primary)   (redundancy)  (public GW)

Принцип: загружаем через свою ноду + пиним в нескольких сервисах для redundancy. Раздаём через собственный gateway или Cloudflare.

Своя IPFS нода: go-ipfs / Kubo

# Установка Kubo (go-ipfs)
wget https://dist.ipfs.tech/kubo/v0.27.0/kubo_v0.27.0_linux-amd64.tar.gz
tar xvzf kubo_v0.27.0_linux-amd64.tar.gz
cd kubo && sudo bash install.sh

# Инициализация
ipfs init --profile server

# Оптимизация конфига для server (не desktop)
ipfs config Addresses.API /ip4/127.0.0.1/tcp/5001
ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
ipfs config --json Swarm.ConnMgr.HighWater 200
ipfs config --json Swarm.ConnMgr.LowWater 100

# Отключаем автоматический GC (управляем вручную)
ipfs config --json Datastore.GCPeriod '"0s"'

Systemd unit:

[Unit]
Description=IPFS Daemon
After=network.target

[Service]
User=ipfs
Environment=IPFS_PATH=/data/ipfs
ExecStart=/usr/local/bin/ipfs daemon --migrate=true --enable-gc=false
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Загрузка и пиннинг

import { create } from 'kubo-rpc-client';
import * as fs from 'fs';

const ipfs = create({ url: 'http://localhost:5001' });

async function uploadFile(filePath: string): Promise<string> {
  const file = fs.readFileSync(filePath);
  const result = await ipfs.add(file, {
    pin: true,     // сразу пиним локально
    cidVersion: 1, // CIDv1 более современный, base32 кодировка
  });
  return result.cid.toString();
}

// Загрузка директории (например, папка с NFT метаданными)
async function uploadDirectory(dirPath: string): Promise<string> {
  const files = [];
  
  for (const filename of fs.readdirSync(dirPath)) {
    files.push({
      path: filename,
      content: fs.readFileSync(`${dirPath}/${filename}`),
    });
  }
  
  let rootCid = '';
  for await (const file of ipfs.addAll(files, { 
    wrapWithDirectory: true,
    pin: true,
    cidVersion: 1,
  })) {
    if (file.path === '') { // root directory
      rootCid = file.cid.toString();
    }
  }
  
  return rootCid; // ipfs://rootCid/filename.json
}

Remote pinning: Pinata и Web3.Storage

Локального пиннинга недостаточно. Если ваш сервер лежит — никто не получит данные. Пиним в двух-трёх сервисах:

// Пиннинг в Pinata через Remote Pin API (IPFS стандарт)
async function pinToPinata(cid: string, name: string): Promise<void> {
  const response = await fetch('https://api.pinata.cloud/psa/pins', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.PINATA_JWT}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      cid,
      name,
      origins: [`/dns4/your-ipfs-node.example.com/tcp/4001/p2p/${YOUR_NODE_ID}`],
    }),
  });
  
  if (!response.ok) throw new Error(`Pinata pin failed: ${response.statusText}`);
}

// Проверка статуса пиннинга
async function checkPinStatus(cid: string): Promise<string> {
  const response = await fetch(`https://api.pinata.cloud/psa/pins?cid=${cid}`, {
    headers: { 'Authorization': `Bearer ${process.env.PINATA_JWT}` },
  });
  const data = await response.json();
  return data.results[0]?.status ?? 'not_found'; // 'queued'|'pinning'|'pinned'|'failed'
}

Стратегия пиннинга для NFT проекта:

  • Собственная нода — первичное хранилище, быстрый доступ
  • Pinata — первый backup, надёжный сервис, платный
  • web3.storage (Filecoin-backed) — второй backup, хранит данные на Filecoin с верифицируемыми deal receipts
  • Nft.storage — специализированно для NFT, Filecoin + IPFS

IPFS Gateway

Браузеры не понимают ipfs:// нативно. Нужен HTTP gateway:

# Nginx как reverse proxy для IPFS gateway
server {
    listen 443 ssl;
    server_name ipfs.yourdomain.com;
    
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        
        # Кешируем IPFS контент — он иммутабельный, можно кешировать навсегда
        proxy_cache ipfs_cache;
        proxy_cache_valid 200 365d;
        add_header Cache-Control "public, max-age=31536000, immutable";
        
        # CORS для браузерного fetch
        add_header Access-Control-Allow-Origin "*";
    }
}

Cloudflare также предоставляет IPFS gateway — через cloudflare-ipfs.com/ipfs/{CID} или через Workers с кастомным доменом. Это хороший способ получить CDN поверх IPFS.

NFT метаданные: стандарт и структура

{
  "name": "Token #42",
  "description": "...",
  "image": "ipfs://bafybeig.../image.png",
  "attributes": [
    { "trait_type": "Background", "value": "Blue" }
  ]
}

Изображение — отдельный CID, метаданные — отдельный CID. В смарт-контракте храним baseURI = "ipfs://bafybei.../", tokenURI возвращает baseURI + tokenId + ".json".

Garbage Collection и мониторинг

# Ручной GC (запускаем по расписанию, не оставляем на автомате)
ipfs repo gc

# Статистика репозитория
ipfs repo stat

# Список всех локальных pins
ipfs pin ls --type=recursive | wc -l

# Проверка что конкретный CID доступен локально
ipfs pin ls bafybeig... 2>/dev/null && echo "pinned" || echo "not pinned"

Мониторинг: Prometheus экспортер для IPFS (ipfs stats bw, ipfs stats repo) + алерт на ipfs swarm peers — если меньше 10 пиров, нода изолирована. Алерт если pin count неожиданно уменьшился (GC удалил что-то важное).

Когда IPFS не нужен

IPFS избыточен для временных данных (аватарки пользователей, которые меняются), данных требующих удаления (GDPR), и данных с частым обновлением. Для этого — обычный S3 или CDN. IPFS имеет смысл для: NFT метаданных и медиа (иммутабельность важна), смарт-контрактных артефактов (ABI, bytecode), decentralized storage с верифицируемостью.