Разработка децентрализованной системы хранения данных
Если вы читаете это после того, как ваш AWS S3 bucket стал причиной регуляторных претензий или после очередного «мы обновляем инфраструктуру» от централизованного хранилища — добро пожаловать. Децентрализованное хранение данных — это не про идеологию, это про конкретные свойства: отсутствие единой точки отказа, верифицируемость содержимого через content addressing и возможность хранить данные без разрешения оператора.
Под «децентрализованным хранением» в 2024 году имеют в виду три принципиально разных стека: IPFS + Filecoin, Arweave и Storj/Sia (incentivized distributed storage). Каждый подходит для своего класса задач.
IPFS + Filecoin: content addressing и экономика хранения
IPFS — это не хранилище, это адресация и транспорт. Content Identifier (CID) — это multihash содержимого файла, вычисленный по умолчанию как SHA2-256 через DAG-структуру (dag-pb с UnixFS). Если файл изменился — CID изменился. Это фундаментальное свойство, которое делает IPFS пригодным для NFT-метаданных, доказуемых документов, иммутабельных артефактов.
Проблема IPFS: пиннинг. Если ваш нод перестал пинить контент — он исчезнет из сети. Filecoin добавляет экономику: storage providers получают FIL за хранение верифицированных deals.
Работа с IPFS Cluster
Для production систем нужен IPFS Cluster — координатор репликации поверх нескольких IPFS-нод. Минимальная конфигурация: 3 ноды, replication factor 2.
// Пример pinning через Cluster REST API
type ClusterPinRequest struct {
CID string `json:"cid"`
ReplicationMin int `json:"replication-min"`
ReplicationMax int `json:"replication-max"`
Name string `json:"name"`
Meta map[string]string `json:"meta"`
}
func PinToCluster(cid string, name string) error {
req := ClusterPinRequest{
CID: cid,
ReplicationMin: 2,
ReplicationMax: 3,
Name: name,
}
body, _ := json.Marshal(req)
resp, err := http.Post(
"http://cluster-api:9094/pins/" + cid,
"application/json",
bytes.NewReader(body),
)
// ...
return err
}
Для загрузки больших файлов критично использовать chunking strategy. По умолчанию IPFS использует size-262144 (256 KB chunks), но для видео и больших бинарников rabin chunker даёт лучшую дедупликацию за счёт content-defined boundaries:
ipfs add --chunker=rabin-262144-524288-1048576 large_file.bin
Filecoin Storage Deals
Прямая работа с Filecoin через Lotus — это низкоуровневый путь. Для production используют Estuary (депрекирован) или современный Lighthouse SDK / web3.storage:
import { Web3Storage } from 'web3.storage'
const client = new Web3Storage({ token: process.env.W3S_TOKEN })
async function storeWithReplication(files: File[]): Promise<string> {
const cid = await client.put(files, {
wrapWithDirectory: false,
onRootCidReady: (rootCid) => {
console.log('Root CID:', rootCid) // доступен до завершения загрузки
},
onStoredChunk: (size) => {
console.log(`Uploaded chunk of ${size} bytes`)
}
})
return cid
}
web3.storage делает hot IPFS pinning + холодный Filecoin deal автоматически. Для enterprise — NFT.Storage с аналогичным API но фокусом на метаданные.
Arweave: permanent storage с однократной оплатой
Arweave — другая модель: платишь один раз, данные хранятся «вечно» (endowment fund рассчитан на 200+ лет при консервативных предположениях об удешевлении хранения). Это принципиально меняет use cases.
Когда Arweave — правильный выбор:
- Smart contract source code и ABI (верифицируемость навсегда)
- NFT-метаданные и медиа (избежать NFT rot)
- Юридические и нотариальные документы
- Протоколы управления и результаты голосований (DAO governance history)
Данные в Arweave — это transaction с data полем и тегами. Теги — ключ к индексации через GraphQL:
import Arweave from 'arweave'
import { WarpFactory } from 'warp-contracts'
const arweave = Arweave.init({
host: 'arweave.net',
port: 443,
protocol: 'https'
})
async function uploadDocument(data: Buffer, mimeType: string, metadata: Record<string, string>) {
const tx = await arweave.createTransaction({ data })
tx.addTag('Content-Type', mimeType)
tx.addTag('App-Name', 'YourDApp')
tx.addTag('Version', '1.0.0')
// Пользовательские теги для поиска через GraphQL
for (const [key, value] of Object.entries(metadata)) {
tx.addTag(key, value)
}
await arweave.transactions.sign(tx, jwk)
const response = await arweave.transactions.post(tx)
return tx.id // это постоянный ID документа
}
Запрос к Arweave через ArQL / GraphQL для поиска документов по тегам:
query FindDocuments($owner: String!, $docType: String!) {
transactions(
owners: [$owner]
tags: [
{ name: "App-Name", values: ["YourDApp"] }
{ name: "Document-Type", values: [$docType] }
]
first: 100
) {
edges {
node {
id
tags { name value }
block { timestamp }
}
}
}
}
Bundlr / Irys: батчевая загрузка и instant finality
Нативные Arweave транзакции подтверждаются ~2 минуты, и это проблема для UX. Irys (бывший Bundlr) решает это через layer 2 поверх Arweave: транзакции подтверждаются мгновенно, батчуются и постятся в Arweave.
import Irys from '@irys/sdk'
const irys = new Irys({
url: 'https://node1.irys.xyz',
token: 'ethereum',
key: privateKey,
})
// Проверка стоимости до загрузки
const price = await irys.getPrice(data.length)
console.log(`Cost: ${irys.utils.fromAtomic(price)} ETH`)
// Загрузка с тегами
const receipt = await irys.upload(data, {
tags: [
{ name: 'Content-Type', value: 'application/json' },
{ name: 'Contract-Address', value: contractAddress },
]
})
// receipt.id — TXID, доступен сразу через https://gateway.irys.xyz/{id}
Гибридная архитектура: горячее + холодное хранение
В реальных системах редко используют только один протокол. Типичная архитектура для DApp с требованиями к производительности и постоянству:
Запись данных:
User → App Backend → [параллельно]:
1. IPFS Cluster (hot, быстрый доступ, ~3 реплики)
2. Irys → Arweave (cold, permanent, 1-2 мин)
3. PostgreSQL (CID + Arweave TXID + метаданные, для поиска)
Чтение данных:
User → App Backend → PostgreSQL (lookup CID/TXID)
→ IPFS Gateway (быстро, если пиннед)
→ Fallback: Arweave Gateway (если IPFS недоступен)
Это даёт: мгновенное чтение через IPFS, гарантию постоянства через Arweave, и поиск через обычную базу данных.
Верификация целостности
Content addressing — это верификация «из коробки» для IPFS: CID — это хэш содержимого. Для Arweave верификация через транзакционные доказательства:
async function verifyArweaveData(txId: string, expectedHash: string): Promise<boolean> {
const tx = await arweave.transactions.get(txId)
const data = await arweave.transactions.getData(txId, { decode: true })
const hash = crypto.createHash('sha256').update(data as Buffer).digest('hex')
return hash === expectedHash
}
Шифрование и контроль доступа
Децентрализованное хранение не означает публичное. Для чувствительных данных — Lit Protocol для threshold encryption с on-chain условиями доступа:
import * as LitJsSdk from '@lit-protocol/lit-node-client'
// Условие доступа: владелец NFT из коллекции
const accessControlConditions = [{
contractAddress: NFT_CONTRACT,
standardContractType: 'ERC721',
chain: 'ethereum',
method: 'balanceOf',
parameters: [':userAddress'],
returnValueTest: { comparator: '>', value: '0' }
}]
// Шифрование перед загрузкой в IPFS
const { ciphertext, dataToEncryptHash } = await LitJsSdk.encryptString(
{ accessControlConditions, dataToEncrypt: sensitiveData },
litNodeClient
)
// Расшифровка — только при выполнении условия on-chain
const decrypted = await LitJsSdk.decryptToString(
{ accessControlConditions, ciphertext, dataToEncryptHash, chain: 'ethereum' },
litNodeClient
)
Стоимостная модель и выбор стека
| Критерий | IPFS + Cluster | Filecoin Deals | Arweave / Irys | Storj |
|---|---|---|---|---|
| Постоянство | Пока пиннед | 1–5 лет по deal | Перманентное | Пока платишь |
| Скорость чтения | Высокая | Медленная (retrieval) | Средняя | Высокая |
| Стоимость | Инфраструктура | ~$0.0001/GB/month | ~$10/GB единоразово | ~$4/TB/month |
| Цензуростойкость | Средняя | Высокая | Очень высокая | Средняя |
| Поиск | Только по CID | Нет | GraphQL по тегам | Нет |
Для NFT-проектов и DAO: Arweave через Irys — единственный разумный выбор, стоимость метаданных незначительна, постоянство критично. Для данных приложений с высокими требованиями к latency: IPFS Cluster с hot replication + Filecoin для архивных копий. Для enterprise с compliance требованиями: гибридная схема с шифрованием через Lit Protocol.







