Skip to main content

IPFS

IPFS is a decentralized protocol and peer-to-peer network that stores and shares hypermedia using content-addressing. It ensures global, permanent access to files by assigning unique cryptographic hashes as addresses, employs a distributed network for resilience, tracks file versions, organizes data with a Merkle DAG, supports offline sharing, and utilizes caching for efficient content retrieval. IPFS is widely used for decentralized file storage, web hosting, DApps, and ensuring data integrity in various domains, including blockchain and cryptocurrency.

Integrating IPFS with a Substrate-based Blockchain

Integrating IPFS with a Substrate-based blockchain allows for decentralized storage solutions in blockchain applications. This guide outlines the process to connect to IPFS, store data, generate a unique storage key, and interact with the blockchain to store and retrieve data CIDs.

Connect to IPFS

First, establish a connection to IPFS for storing and retrieving data.

import { create } from 'ipfs-http-client';
const ipfs = create({ url: <IPFS_GATEWAY> });

Explanation: This snippet initializes the IPFS client, allowing your application to communicate with the IPFS network.

Initialize Blockchain API Connection

Connect to your Substrate blockchain using Polkadot.js API.

import { ApiPromise, WsProvider } from '@polkadot/api';
import { defaultOptions } from '@peaq-network/types';

const provider = new WsProvider('wss://your-substrate-node-url');
const api = await ApiPromise.create({ provider, ...defaultOptions });

Explanation: This code establishes a connection to your Substrate-based blockchain, enabling interactions with the blockchain.

Store Data in IPFS and Blockchain

Store data on IPFS and record the CID in the blockchain.

const data = “Hello World”;
const itemType = “Test-data”;
const keyring = new Keyring({ type: 'sr25519' });
// Add Alice to our keyring with a hard-derivation path (empty phrase, so uses dev)
const alice = keyring.addFromUri('//Alice');
const added = await ipfs.add(data);
const cid = added.cid.toString();
await api.tx.peaqStorage.addItem(itemType, cid).signAndSend(alice);

Explanation: After adding data to IPFS and receiving a CID, this snippet demonstrates generating a storage key and using it to store the CID on the blockchain.

Create a Unique Storage Key

Generate a unique key for blockchain storage.

import { decodeAddress, blake2AsHex } from '@polkadot/util-crypto';

function createStorageKey(address, itemType) {
const addressBytes = decodeAddress(address);
const itemTypeBytes = new TextEncoder().encode(itemType);
const combined = new Uint8Array([...addressBytes, ...itemTypeBytes]);
const storageKey = blake2AsHex(combined, 256);
return storageKey;
}

Explanation: Utilizes the user's address and data type to generate a unique key for identifying stored data on the blockchain.

Retrieve Data from Blockchain and IPFS

Fetch data from IPFS using a CID obtained from the blockchain.

const storageKey = createStorageKey(alice.address, itemType);
const cid = await api.query.peaqStorage.getItem(storageKey);
const data = await ipfs.cat(cid.toString());
console.log(new TextDecoder().decode(data));

Explanation: This function retrieves the CID from the blockchain using a storage key and fetches the corresponding data from IPFS.

This guide provides a foundational approach for leveraging IPFS with Substrate-based blockchains, emphasizing decentralized storage solutions and data integrity within blockchain applications.