SECTION 1: LEARNING OBJECTIVES

By the end of this lesson, you will be able to:

  • Define decentralised storage and its role in blockchain ecosystems.

  • Explain content-addressed storage and its advantages over location-addressed storage.

  • Understand the architecture of IPFS and its core components.

  • Describe incentive layers (Filecoin, Arweave, Storj).

  • Differentiate between on-chain and off-chain data storage strategies.

  • Identify use cases for decentralised storage in digital finance.

  • Implement a basic content-addressed storage simulation in Python.

  • Develop a framework for selecting decentralised storage solutions.


SECTION 2: WHAT IS DECENTRALISED STORAGE?

2.1 Definition

Decentralised storage refers to a system where data is stored across a distributed network of nodes rather than in a centralised data centre. Unlike traditional cloud storage (AWS S3, Google Cloud), decentralised storage eliminates single points of failure, reduces censorship risk, and gives users control over their data.

2.2 Content-Addressed vs Location-Addressed Storage

The fundamental shift in decentralised storage is moving from location-addressed to content-addressed storage:

Location-Addressed Storage (Traditional):

  • Data is found by where it is stored (e.g., https://server.com/file.pdf)

  • The server is a single point of failure

  • Links break if the server moves or shuts down

  • Example: HTTP, FTP

Content-Addressed Storage (Decentralised):

  • Data is found by what it is (its cryptographic hash)

  • The hash uniquely identifies the content

  • Any node can serve the content

  • Links are permanent and verifiable

  • Example: IPFS (ipfs://Qm...), Arweave

text
┌─────────────────────────────────────────────────────────────────────────────┐
│                    CONTENT ADDRESSING                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Traditional HTTP:                                                         │
│  https://website.com/images/photo.jpg                                      │
│  └─────────────┘ └─────────────┘                                          │
│        Location          File name                                        │
│    (Server address)    (Name, not content)                               │
│                                                                             │
│  Decentralised Content-Addressing:                                        │
│  ipfs://QmZ4tDu... /                                                      │
│         └──────────┘                                                      │
│          Cryptographic Hash                                               │
│         (Identifies content, not location)                                │
│                                                                             │
│  Advantages:                                                                │
│  • Immutable - content changes = different hash                          │
│  • Verifiable - users can verify integrity                               │
│  • Permanent - hash always points to same content                        │
│  • Decentralised - any node can serve the content                        │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

SECTION 3: IPFS (INTERPLANETARY FILE SYSTEM)

3.1 Architecture

IPFS is a peer-to-peer protocol for storing and sharing content-addressed data. Its architecture consists of several key components:

1. Identity Layer:
Each node in the IPFS network has a unique peer identity (PeerID) derived from its public key. This enables secure communication and authentication between nodes.

2. Network Layer:
IPFS nodes communicate using libp2p, a modular networking stack that supports multiple transport protocols (TCP, WebSocket, QUIC). It handles peer discovery, connection management, and secure communication.

3. Routing Layer:
IPFS uses a Distributed Hash Table (DHT) to find which nodes are storing specific content. When a node requests a file, the DHT helps locate peers that have the content.

4. Exchange Layer:
The Bitswap protocol manages the exchange of data blocks between nodes. It uses a strategy to prioritise fetching the most valuable or requested blocks first.

5. Merkle DAG Layer:
IPFS structures data using a Merkle Directed Acyclic Graph (DAG). Each block is addressed by its hash, and blocks can link to other blocks, forming a directed graph. This enables:

  • Deduplication (same content stored once)

  • Versioning (different versions have different hashes)

  • Efficient retrieval (only fetch needed blocks)

6. Naming Layer (IPNS):
IPNS provides mutable names for content. While IPFS addresses are immutable (hash-based), IPNS allows users to publish a name that can point to different content over time, enabling content updates.

3.2 IPFS Components

 
 
Component Purpose Description
CID (Content Identifier) Content addressing Hash-based identifier (e.g., Qm...)
Merkle DAG Data structuring Linked data blocks with hash verification
DHT Discovery Finds nodes storing content
Bitswap Data exchange Block trading between nodes
IPNS Mutable naming Human-readable, updatable names
Filecoin Incentive layer Economic incentives for storage

3.3 IPFS Use Cases in Digital Finance

 
 
Use Case Description Benefit
DeFi Data Storage Store historical transaction data Permanent, verifiable records
NFT Storage Store NFT metadata and assets Decentralised, permanent
Tokenised Assets Store asset documentation Verifiable provenance
KYC Documents Store encrypted identity documents User-controlled privacy
Smart Contract Code Store off-chain code references Verification of code
Research Data Store financial models and analytics Reproducibility

SECTION 4: INCENTIVISED STORAGE LAYERS

4.1 Filecoin

Filecoin is a decentralised storage network that adds economic incentives on top of IPFS.

Key Concepts:

  • Storage Miners: Nodes that provide storage space and earn Filecoin (FIL) tokens.

  • Retrieval Miners: Nodes that provide fast retrieval of content.

  • Proof-of-Storage: Cryptographic proofs that miners are actually storing data.

    • Proof-of-Replication (PoRep): Proves data has been stored uniquely.

    • Proof-of-Spacetime (PoSt): Proves data is continuously stored over time.

How It Works:

  1. Client wants to store data.

  2. Client and storage miner agree on a deal (price, duration).

  3. Data is stored, and the miner provides proofs.

  4. Client pays Filecoin to the miner.

  5. If data is lost, the miner is penalised.

Storage Process:

text
Client → Deal with Miner → Data Transfer → PoRep → PoSt (ongoing) → Payment

Current Metrics:

  • Network Storage Capacity: 20+ EiB (exabytes)

  • Active Miners: 3,000+

  • Deal Volume: Growing rapidly

4.2 Arweave

Arweave offers permanent, one-time payment storage.

Key Concepts:

  • Permaweb: A permanent, decentralised web built on Arweave.

  • Storage Endowment: Users pay once, and the endowment pays miners over time.

  • Proof of Access (PoA): Miners must prove they can access historical data.

Unique Features:

  • One-time payment for permanent storage

  • Designed for long-term data archival

  • Growing ecosystem of “permaweb” applications

4.3 Storj

Storj is a decentralised cloud storage platform with S3-compatible APIs.

Key Concepts:

  • Storage Nodes: Nodes providing storage space.

  • Satellite Nodes: Coordinate storage and retrieval.

  • Tardigrade: Enterprise-grade decentralised storage.

Features:

  • S3-compatible API (easy migration)

  • Encryption by default

  • Focus on performance and reliability

4.4 Comparison of Incentivised Storage

 
 
Feature Filecoin Arweave Storj
Payment Model Ongoing (deals) One-time (permanent) Ongoing
Storage Model Contract-based Permanent Contract-based
Blockchain Native (Filecoin) Native (Arweave) Ethereum + own
Retrieval Speed Moderate Moderate Fast
S3 Compatible No No Yes
Best For General storage, DeFi Permanent archival Enterprise migration

SECTION 5: STORAGE STRATEGIES FOR BLOCKCHAIN APPLICATIONS

5.1 On-Chain vs Off-Chain Storage

text
┌─────────────────────────────────────────────────────────────────────────────┐
│                    ON-CHAIN VS OFF-CHAIN STORAGE                            │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ON-CHAIN STORAGE                                                           │
│  ┌──────────────────────────────────────────────────────────────────────┐   │
│  │ • Data stored in blockchain state                                    │   │
│  │ • Expensive (gas costs)                                             │   │
│  │ • Limited capacity                                                  │   │
│  │ • Immutable, verifiable                                             │   │
│  │ • Best for: Small data, critical state, consensus data              │   │
│  │ • Examples: Account balances, smart contract code, governance data  │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  OFF-CHAIN STORAGE                                                          │
│  ┌──────────────────────────────────────────────────────────────────────┐   │
│  │ • Data stored outside blockchain                                     │   │
│  │ • Inexpensive                                                        │   │
│  │ • Unlimited capacity                                                 │   │
│  │ • Verifiable via cryptographic hashes                               │   │
│  │ • Best for: Large files, metadata, historical data                  │   │
│  │ • Examples: NFT assets, KYC documents, app data                     │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  HYBRID APPROACH                                                            │
│  ┌──────────────────────────────────────────────────────────────────────┐   │
│  │ • Store hash on-chain, data off-chain                               │   │
│  │ • Best of both worlds                                                │   │
│  │ • Verification via hash                                              │   │
│  │ • Example: ERC-721 NFT stores metadata URI on-chain                │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

5.2 Storage Architecture Patterns

 
 
Pattern Description Use Case
Hash-on-Chain Store CID on-chain, data off-chain NFTs, document verification
Full On-Chain All data stored on-chain Simple DApps, governance
Off-Chain Reference Data stored off-chain with on-chain pointer Large applications
Distributed Storage Data distributed across storage network Decentralised apps
Hybrid Critical data on-chain, rest off-chain Most DeFi protocols

SECTION 6: IMPLEMENTATION IN PYTHON

python
# ===================================================================
# MODULE 4, LESSON 3: DECENTRALISED STORAGE
# ===================================================================

import hashlib
import json
import time
import base64
from typing import Dict, List, Optional, Any
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import warnings
warnings.filterwarnings('ignore')

print("="*70)
print("DECENTRALISED STORAGE")
print("="*70)

# ----------------------------------------------------------------
# PART A: CONTENT-ADDRESSED STORAGE SIMULATION
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART A: Content-Addressed Storage Simulation")
print("-"*60)

class ContentAddressableStorage:
    """
    Simulated content-addressed storage system.
    """
    def __init__(self):
        self.storage: Dict[str, bytes] = {}
        self.pinned: set = set()
        self.metrics = {
            'total_objects': 0,
            'total_bytes': 0,
            'pinned_objects': 0,
            'retrieval_requests': 0
        }
    
    def add_content(self, data: bytes) -> str:
        """
        Store content and return its content address (CID).
        """
        # Calculate content hash
        content_hash = hashlib.sha256(data).hexdigest()
        cid = f"Qm{content_hash[:44]}"  # Simplified CID format
        
        # Store content
        self.storage[cid] = data
        self.metrics['total_objects'] += 1
        self.metrics['total_bytes'] += len(data)
        
        print(f"Stored content with CID: {cid}")
        print(f"  Size: {len(data)} bytes")
        return cid
    
    def get_content(self, cid: str) -> Optional[bytes]:
        """
        Retrieve content by CID.
        """
        self.metrics['retrieval_requests'] += 1
        
        if cid in self.storage:
            print(f"Retrieved content: {cid}")
            return self.storage[cid]
        else:
            print(f"Content not found: {cid}")
            return None
    
    def pin_content(self, cid: str) -> bool:
        """
        Pin content to keep it permanently.
        """
        if cid in self.storage:
            self.pinned.add(cid)
            self.metrics['pinned_objects'] += 1
            print(f"Pinned content: {cid}")
            return True
        return False
    
    def get_metrics(self) -> Dict:
        return {
            'total_objects': self.metrics['total_objects'],
            'total_bytes': self.metrics['total_bytes'],
            'pinned_objects': self.metrics['pinned_objects'],
            'retrieval_requests': self.metrics['retrieval_requests']
        }

# Create storage system
storage = ContentAddressableStorage()

print("Content-Addressable Storage Simulation:")

# Store data
documents = [
    b"Hello, Blockchain! This is a sample document.",
    b"Smart contract code: function transfer(address to, uint amount)",
    b"NFT metadata: {'name': 'Digital Art', 'artist': 'Alice'}",
    b"Financial report: Q4 2024 earnings"
]

print("\nStoring content...")
cids = []
for doc in documents:
    cid = storage.add_content(doc)
    cids.append(cid)

# Retrieve content
print("\nRetrieving content...")
for cid in cids[:2]:
    content = storage.get_content(cid)
    if content:
        print(f"  Content preview: {content[:50]}...")

# Pin content
print("\nPinning content...")
storage.pin_content(cids[0])

# Metrics
metrics = storage.get_metrics()
print(f"\nStorage Metrics:")
print(f"  Total Objects: {metrics['total_objects']}")
print(f"  Total Bytes: {metrics['total_bytes']}")
print(f"  Pinned Objects: {metrics['pinned_objects']}")
print(f"  Retrieval Requests: {metrics['retrieval_requests']}")

# ----------------------------------------------------------------
# PART B: ON-CHAIN VS OFF-CHAIN STORAGE COMPARISON
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART B: On-Chain vs Off-Chain Storage Comparison")
print("-"*60)

comparison_data = {
    'Feature': [
        'Cost per MB',
        'Storage Limit',
        'Data Availability',
        'Verification',
        'Immutability',
        'Retrieval Speed',
        'Privacy',
        'Best For'
    ],
    'On-Chain': [
        'Very High (~$10,000)',
        'Very Low (~KB)',
        'Always Available',
        'Native',
        'Permanent',
        'Fast (if stored)',
        'Public (by default)',
        'Critical state'
    ],
    'Off-Chain (IPFS)': [
        'Low (~$0.01)',
        'Very High (PB+)',
        'Pinning-dependent',
        'Hash-based',
        'Permanent (if pinned)',
        'Moderate',
        'Controlled (encryption)',
        'Large files'
    ],
    'Incentivised (Filecoin)': [
        'Medium (~$0.001-0.01)',
        'Very High (EB)',
        'Guaranteed (contract)',
        'Proof-based',
        'Permanent (contract)',
        'Variable',
        'Controlled',
        'Enterprise storage'
    ]
}

comparison_df = pd.DataFrame(comparison_data)
print(comparison_df.to_string(index=False))

# ----------------------------------------------------------------
# PART C: STORAGE METRICS VISUALISATION
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART C: Storage Metrics Visualisation")
print("-"*60)

# Simulate storage cost comparison
platforms = ['IPFS (Pinning)', 'Filecoin', 'Arweave', 'Storj', 'AWS S3']
cost_per_gb = [0.05, 0.03, 0.10, 0.02, 0.25]
storage_capacity = [50, 100, 30, 40, 80]  # relative index
retrieval_speed = [3, 2, 1, 4, 5]  # relative index (higher = faster)
decentralisation = [5, 5, 4, 3, 1]  # relative index (higher = more decentralised)

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

ax1 = axes[0]
x = np.arange(len(platforms))
width = 0.35
ax1.bar(x - width/2, cost_per_gb, width, label='Cost per GB ($)', color='orange', alpha=0.7)
ax1.bar(x + width/2, [d/10 for d in decentralisation], width, label='Decentralisation (scaled)', color='blue', alpha=0.7)
ax1.set_xticks(x)
ax1.set_xticklabels(platforms, rotation=45, ha='right')
ax1.set_title('Storage Solutions: Cost vs Decentralisation')
ax1.legend()
ax1.grid(True, alpha=0.3)

ax2 = axes[1]
ax2.scatter(retrieval_speed, cost_per_gb, s=200, c=decentralisation, cmap='viridis', alpha=0.8)
for i, platform in enumerate(platforms):
    ax2.annotate(platform, (retrieval_speed[i], cost_per_gb[i]), xytext=(5, 5), textcoords='offset points', fontsize=8)
ax2.set_xlabel('Retrieval Speed (relative)')
ax2.set_ylabel('Cost per GB ($)')
ax2.set_title('Storage Solutions: Speed vs Cost')
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('decentralised_storage_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
print("Storage comparison chart saved as 'decentralised_storage_comparison.png'")

# ----------------------------------------------------------------
# PART D: SUMMARY AND RECOMMENDATIONS
# ----------------------------------------------------------------

print("\n" + "="*70)
print("PART D: Summary and Recommendations")
print("="*70)

print("""
Decentralised Storage – Key Takeaways:

1. Content-addressed storage uses cryptographic hashes instead of locations.
2. IPFS provides a decentralised P2P storage network with content addressing.
3. Key IPFS components: CID, Merkle DAG, DHT, Bitswap, IPNS.
4. Filecoin adds economic incentives with proof-of-storage mechanisms.
5. Arweave offers permanent storage with one-time payment.
6. Storj provides S3-compatible decentralised storage.
7. Storage strategies: on-chain (critical), off-chain (large data), hybrid (hash + data).

Storage Selection Framework:
  - For permanent data: Arweave (one-time payment).
  - For general storage: Filecoin (cost-effective, provable).
  - For enterprise migration: Storj (S3 compatible).
  - For development: IPFS pinning services (Infura, Pinata).
  - For critical state: On-chain storage.
  - For NFT assets: IPFS + Filecoin (provenance + persistence).
""")

print("="*70)
print("END OF LESSON 3 – MODULE 4")
print("="*70)