A decentralized storage system built on Substrate with game-theoretic guarantees. Storage providers lock stake and face slashing for data loss, while the chain acts as a credible threat rather than the hot path.
- Storage providers register with stake and offer storage services
- Clients create buckets and upload data off-chain
- Storage agreements bind providers to store data for agreed durations
- Challenges enforce accountability through slashing
Normal operations (reads, writes) happen off-chain. The chain is only touched for setup, checkpoints, and disputes.
Get running in 5 minutes:
# Install just (command runner)
cargo install just
# One-time setup: downloads binaries + builds everything
just setup
# Start blockchain network + provider node
just start-chain # Terminal 1
just start-provider # Terminal 2
# Terminal 2:
# Setup (register provider, create bucket, establish agreement)
# Upload test data + challenge
just demoThat's it! Your local network is running with a provider ready to accept data.
- Downloaded:
polkadot,polkadot-omni-node,zombienet,chain-spec-builder - Built: runtime, pallet, provider node, client SDK
- Started: Relay chain (2 validators) + Parachain (1 collator) + Provider node
-
Configure on-chain - Register provider, create bucket, setup agreement
- See: Quick Start Guide
-
Run tests - Verify everything works
bash scripts/verify-setup.sh # Check on-chain setup bash scripts/quick-test.sh # Run automated tests
-
Try the demo - Quick end-to-end test (after on-chain setup)
just demo-setup # Register provider, create bucket, establish agreement just demo-upload # Upload test data with timestamp
-
Upload data - Use the client SDK or HTTP API
- See: Client Documentation
just --list # Show all available commands
just check # Verify prerequisites
just build # Build the project
just start-chain # Start blockchain only
just start-chain # Start blockchain
just start-provider # Start provider node
just health # Check provider healthπ Full Documentation - Complete documentation index
| Document | Description |
|---|---|
| Quick Start Guide | Get running fast (5 min) |
| Manual Testing Guide | Complete testing workflow |
| Extrinsics Reference | Complete blockchain API |
| Payment Calculator | Calculate agreement costs |
| Architecture Design | System design & rationale |
| Implementation Details | Technical specs |
Two types of nodes work together:
ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
β BLOCKCHAIN LAYER β β STORAGE LAYER β
β β β β
β Parachain Node ββββββΆβ Provider Node β
β (Polkadot Omni Node) β RPC β (HTTP Server) β
β β β β
β β’ Stake & registration β β β’ Data storage β
β β’ Agreements β β β’ MMR commitments β
β β’ Checkpoints β β β’ Chunk serving β
β β’ Challenges/slashing β β β’ Replica sync β
ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
Infrequent Hot path
(setup, disputes) (all data operations)
| Node | Purpose | Run by |
|---|---|---|
| Parachain Node (Omni Node + Runtime) | Blockchain consensus, state transitions, finality | Collators (parachain validators) |
| Provider Node (HTTP Server) | Store actual data, serve clients, respond to challenges | Storage providers |
Storage providers run both nodes:
- Parachain node: Participates in blockchain consensus
- Provider node: Handles actual data storage/serving
scalable-web3-storage/
βββ pallet/ # Substrate pallet (on-chain logic)
βββ runtime/ # Parachain runtime
βββ provider-node/ # Off-chain storage server (HTTP API)
βββ client/ # Client SDK for applications
βββ primitives/ # Shared types and utilities
βββ scripts/ # Helper scripts
βββ docs/ # Documentation
βββ getting-started/ # Quick start guides
βββ testing/ # Testing procedures
βββ reference/ # API references
βββ design/ # Architecture docs
- Rust 1.74+ with wasm32-unknown-unknown target
- Cargo
# Build everything
cargo build --release
# Or use just
just build# Unit tests
cargo test
# Integration tests with running system
just start-chain # Terminal 1
just start-provider # Terminal 2
just demo # Terminal 3The provider node uses environment variables for configuration:
| Variable | Description | Default |
|---|---|---|
PROVIDER_ID |
Provider's on-chain account ID (SS58 format) | Required |
CHAIN_RPC |
Parachain WebSocket RPC endpoint | ws://127.0.0.1:2222 |
BIND_ADDR |
HTTP server bind address | 0.0.0.0:3333 |
DATA_DIR |
Directory for storing data | ./data |
RUST_LOG |
Log level configuration | storage_provider_node=debug |
use storage_client::StorageUserClient;
// Connect to provider
let mut client = StorageUserClient::new(config);
client.connect_chain().await?;
// Upload data (off-chain)
let data = b"Hello, decentralized storage!";
let result = client.upload(bucket_id, data).await?;
// Verify upload
let downloaded = client.download(bucket_id, result.seq).await?;
assert_eq!(data, downloaded);See Client README for complete examples.
- Off-chain storage: All data operations happen off-chain via HTTP
- On-chain accountability: Stake-based provider registration with slashing
- Content-addressed: All data is blake2-256 content-addressed
- MMR commitments: Merkle Mountain Range for efficient proofs
- Challenge mechanism: Anyone can challenge providers to prove data possession
- Replica support: Primary providers can sync to replica providers
- Flexible agreements: Customizable duration, capacity, pricing per provider
-
Provider Setup (on-chain)
- Provider registers with stake
- Provider configures settings (pricing, duration limits)
-
Bucket Creation (on-chain)
- Client creates bucket
- Client adds members (writers, readers)
- Client requests storage agreement with provider
- Provider accepts agreement
-
Data Storage (off-chain)
- Client uploads chunks to provider via HTTP
- Provider stores and builds MMR commitment
- Provider signs commitment
-
Checkpoint (on-chain)
- Client submits checkpoint with provider signatures
- Providers become liable for committed data
-
Verification (off-chain)
- Client spot-checks random chunks periodically
- Client verifies data integrity via hashes
-
Dispute (on-chain, rare)
- If provider fails to serve data, client challenges
- Provider must respond with proof or be slashed
See Manual Testing Guide for:
- Local development setup
- Rococo testnet deployment
- Production deployment checklist
- Read CLAUDE.md - Project overview, build commands, and code review guidelines
- Read the Architecture Design
- Check Implementation Details
- Run tests:
cargo test - Follow existing code style:
cargo fmt --check
Apache-2.0