Розробка системи кешування контенту на блокчейні

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

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

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

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1285
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1197
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    902
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

Розробка системи кеширування контенту на блокчейні

Постановка задачи звучить так: «хочемо хранить контент децентрализовано, але потрібно щоб завантажувався швидко». Це протиріччя у самому запиті. IPFS — повільний, Arweave — повільний, Filecoin — повільний. Блокчейн взагалі не передбачений для зберігання великих обсягів даних. Система кеширування контенту на блокчейні — це не «хранити контент у блокчейні», це «використовувати блокчейн для управління розподіленим кешем», де сам контент знаходится у decentralized storage, а права доступу, стан кеша й економіка кеширування — на цепі.

Архітектурна модель: що де зберігається

Правильне розділення відповідальності:

Контент (файли, відео, дані)     → IPFS / Arweave / Filecoin
Метаданні й CID                   → On-chain або у calldata
Права доступу й DRM               → Smart contracts
Економіка кеширування             → Token incentives (on-chain)
CDN / edge кеш                    → Традиційна інфраструктура або decentralized (Fleek, Spheron)

Блокчейн — не база даних для контенту. Зберігати 1MB on-chain на Ethereum mainnet коштує ~$3000+ (при газі 30 gwei, 16 gas/byte для calldata). EIP-4844 blobs дешевше — ~$0.01 за 128KB — але дані доступні тільки ~18 днів.

Content Registry: контракт управління

Центральний елемент — реєстр контенту, який відслідковує що де зберігається й хто має права:

contract ContentRegistry {
    struct ContentItem {
        bytes32 contentId;        // keccak256(originalUrl або uuid)
        string ipfsCid;           // IPFS CID (CIDv1 base32)
        string arweaveTxId;       // опціонально: Arweave для постійного зберігання
        address publisher;
        uint256 publishedAt;
        uint256 size;             // у байтах
        ContentType contentType;
        AccessModel accessModel;
        bool active;
    }
    
    enum ContentType { Image, Video, Document, Data, Code }
    enum AccessModel { Public, TokenGated, Subscription, PaidPerView }
    
    mapping(bytes32 => ContentItem) public content;
    mapping(bytes32 => mapping(address => bool)) public accessGrants;
    
    event ContentPublished(bytes32 indexed contentId, string ipfsCid, address publisher);
    event ContentAccessed(bytes32 indexed contentId, address user, uint256 timestamp);
    
    function publishContent(
        bytes32 contentId,
        string calldata ipfsCid,
        string calldata arweaveTxId,
        uint256 size,
        ContentType contentType,
        AccessModel accessModel
    ) external {
        require(content[contentId].publisher == address(0), "Already exists");
        
        content[contentId] = ContentItem({
            contentId: contentId,
            ipfsCid: ipfsCid,
            arweaveTxId: arweaveTxId,
            publisher: msg.sender,
            publishedAt: block.timestamp,
            size: size,
            contentType: contentType,
            accessModel: accessModel,
            active: true
        });
        
        emit ContentPublished(contentId, ipfsCid, msg.sender);
    }
}

Token-gated доступ

ERC-721 або ERC-1155 як пропуск до контенту — стандартна практика для NFT-гейтед контенту:

interface IAccessController {
    function hasAccess(bytes32 contentId, address user) external view returns (bool);
}

contract NFTGatedAccess is IAccessController {
    ContentRegistry public registry;
    
    mapping(bytes32 => address) public contentGates; // contentId => NFT contract
    mapping(bytes32 => uint256) public requiredTokenId; // 0 = any token from collection
    
    function hasAccess(bytes32 contentId, address user) external view override returns (bool) {
        ContentRegistry.ContentItem memory item = registry.content(contentId);
        
        if (item.accessModel == ContentRegistry.AccessModel.Public) return true;
        
        address gateContract = contentGates[contentId];
        if (gateContract == address(0)) return item.publisher == user;
        
        IERC721 nft = IERC721(gateContract);
        uint256 tokenId = requiredTokenId[contentId];
        
        if (tokenId == 0) {
            return nft.balanceOf(user) > 0;
        } else {
            return nft.ownerOf(tokenId) == user;
        }
    }
}

Децентралізована CDN з токен-інцентивами

Ідея: узли кеша (cache nodes) отримують награду за зберігання й раздачу контенту. Це модель Filecoin, але для hot cache (швидкий доступ), не cold storage.

Cache Node Registry

contract CacheNetwork {
    struct CacheNode {
        address operator;
        string endpoint;          // URL API ноди
        uint256 stake;            // Стейк для участі
        uint256 bandwidthServed;  // Байт, обслужених нодою
        uint256 reputationScore;
        bool active;
    }
    
    struct CacheJob {
        bytes32 contentId;
        address requester;
        uint256 rewardPerGB;
        uint256 duration;         // секунди
        uint256 deadline;
    }
    
    mapping(address => CacheNode) public nodes;
    mapping(bytes32 => CacheJob) public jobs;
    
    uint256 public constant MIN_STAKE = 0.1 ether;
    
    function registerNode(string calldata endpoint) external payable {
        require(msg.value >= MIN_STAKE, "Insufficient stake");
        nodes[msg.sender] = CacheNode({
            operator: msg.sender,
            endpoint: endpoint,
            stake: msg.value,
            bandwidthServed: 0,
            reputationScore: 100,
            active: true
        });
    }
    
    function postCacheJob(
        bytes32 contentId,
        uint256 rewardPerGB,
        uint256 duration
    ) external payable {
        // Escrow для оплати кеш-нод
        jobs[contentId] = CacheJob({
            contentId: contentId,
            requester: msg.sender,
            rewardPerGB: rewardPerGB,
            duration: duration,
            deadline: block.timestamp + duration
        });
    }
}

Proof of Bandwidth: як доказати що нода раздавала контент

Основна складність: верифікувати off-chain роботу on-chain. Кілька підходів:

Challenge-response (оптимістичний): нода заявляє про доставку X GB. Challenger може оспорити, запросивши proof. Нода повинна надати log з підписаними запитами користувачів (merkle tree з request logs). Якщо не може — slashing.

Signed receipts: кожен користувач при отриманні файлу підписує receipt (timestamp + contentHash + userAddress). Нода аккумулює receipts, періодично публікує merkle root on-chain. Дозволяє честиво атрибутувати bandwidth.

// Off-chain логіка cache node
interface ServingReceipt {
  contentId: string;
  userAddress: string;
  bytesServed: number;
  timestamp: number;
  userSignature: string;  // підпись користувача
}

async function claimBandwidthReward(receipts: ServingReceipt[]) {
  // Собираємо merkle tree з receipts
  const leaves = receipts.map(r => 
    ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(
      ["bytes32", "address", "uint256", "uint256"],
      [r.contentId, r.userAddress, r.bytesServed, r.timestamp]
    ))
  );
  
  const tree = new MerkleTree(leaves, keccak256, { sortPairs: true });
  const root = tree.getHexRoot();
  
  // Публікуємо root on-chain
  await cacheContract.submitBandwidthClaim(root, totalBytesServed, receipts.length);
}

IPFS Pinning і доступність контенту

IPFS без pinning service — ненадійний. Контент видаляється з локального кеша нод після garbage collection. Для production системи потрібен явний пінінг.

Децентралізований pinning через смарт-контракт

contract PinningMarket {
    struct PinRequest {
        string cid;
        address requester;
        uint256 payment;        // total payment в escrow
        uint256 replicationFactor; // скільки нод повинні зберігати
        uint256 duration;
        uint256 activeUntil;
        address[] pinners;     // хто пінніт
    }
    
    mapping(bytes32 => PinRequest) public requests;
    
    function requestPin(
        string calldata cid,
        uint256 replicationFactor,
        uint256 duration
    ) external payable {
        bytes32 requestId = keccak256(abi.encodePacked(cid, msg.sender, block.timestamp));
        requests[requestId] = PinRequest({
            cid: cid,
            requester: msg.sender,
            payment: msg.value,
            replicationFactor: replicationFactor,
            duration: duration,
            activeUntil: block.timestamp + duration,
            pinners: new address[](0)
        });
    }
    
    function acceptPin(bytes32 requestId) external {
        PinRequest storage req = requests[requestId];
        require(req.pinners.length < req.replicationFactor, "Fully replicated");
        // Нода берет задання на пінніг
        req.pinners.push(msg.sender);
    }
    
    // Періодично нода доказує що файл доступний через Proof of Storage
    function submitStorageProof(bytes32 requestId, bytes calldata proof) external {
        // Верифікуємо через verifiable delay function або challenge-response
        _verifyStorageProof(requestId, proof);
        // Розблокуємо частину payment
        _releasePartialPayment(requestId, msg.sender);
    }
}

Готові рішення: Filecoin/Estuary для довгостроквього зберігання, web3.storage (Storacha), Pinata або NFT.Storage з API. Кастомна реалізація виправдана якщо потрібен специфічний контроль над економікою.

Content Addressing й дедупілікація

IPFS CIDv1 — content-addressed: одинакові дані дають одинаковий CID. Автоматична дедупілікація на рівні зберігання. Але потрібно правильно чанковувати:

import { create } from "ipfs-http-client";

const ipfs = create({ url: "https://ipfs.infura.io:5001" });

async function uploadWithChunking(data: Buffer): Promise<string> {
  const result = await ipfs.add(data, {
    chunker: "rabin-262144-524288-1048576",  // rabin chunking для кращої дедупілікації
    cidVersion: 1,
    hashAlg: "sha2-256",
  });
  return result.cid.toString();
}

Rabin chunking розбиває файли по content-defined boundaries — одне змінення в файлі міняє тільки невелику частину chunks, а не весь файл. Важливо для великих файлів з інкрементальними оновленнями.

Продуктивність: гібридна архітектура

Для реального приложения потрібен шар швидкого доступу поверх децентралізованого зберігання:

Користувач
    ↓
Edge CDN (Cloudflare / Akamai) — hot кеш, <100ms
    ↓ cache miss
IPFS Gateway кластер (власні ноди) — warm кеш, <1s
    ↓ cache miss
IPFS Network / Arweave — cold storage, 2-30s

On-chain компонент: користувач запитує доступ → смарт-контракт верифікує права → видає signed URL або access token → клієнт йде на CDN з цим токеном.

Стек розробки

Компонент Технологія
Content storage IPFS (Kubo) + Arweave для perma
Pinning web3.storage API або Estuary
Registry контракт Solidity + Foundry
Access control ERC-721 gating + Lit Protocol для encryption
Edge cache Cloudflare Workers + R2
Bandwidth proof Merkle receipts + optimistic verification
Node SDK TypeScript + helia (новий IPFS JS)

Коли це має смисл

Система виправдана, якщо:

  • Потрібна censorship resistance (контент не може бути видалений централізованим рішенням)
  • Правоволодільці хочуть on-chain verifiable права й автоматичні royalties
  • Потрібна прозора економіка для операторів кеш-нод

Якщо задача просто «швидко видавати файли» — достатньо Cloudflare + S3.

Сроки

MVP з registry, IPFS зберіганням й token-gated доступом — 4–6 тижнів. Повна система з incentivized cache nodes, bandwidth proofs, governance — 3–4 місяці.