DEV Community

Cover image for A Comprehensive Guide to Storing Files on IPFS and Ethereum with QuickNode
Dev-suite
Dev-suite

Posted on

A Comprehensive Guide to Storing Files on IPFS and Ethereum with QuickNode

Introduction

Running your own dedicated Ethereum node is an idea that crosses the minds of most Web3 builders, tinkerers, and blockchain enthusiasts at some point. But what does it entail, and how viable of an option is it to set up on your own? In this tutorial, we will explore how to store files on IPFS (InterPlanetary File System) and store their corresponding hashes on the Ethereum blockchain using QuickNode, a leading provider of Ethereum and IPFS nodes.

Step 1: Setting Up the Development Environment
To get started, make sure you have Node.js installed on your machine. Open a terminal and run the following command to install the necessary dependencies:

npm install web3@^1.5.3 express@^4.17.1 multer@^1.4.4 ipfs-mini@^3.1.0

Enter fullscreen mode Exit fullscreen mode

Step 2: Creating the Smart Contract
Let's start by creating a simple smart contract that will allow us to store and retrieve IPFS hashes on the Ethereum blockchain. Create a new file called IPFSStorage.sol and add the following code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract IPFSStorage {
    mapping(uint256 => string) private ipfsHashes;

    event HashStored(uint256 indexed id, string ipfsHash);

    function storeHash(uint256 id, string memory ipfsHash) public {
        ipfsHashes[id] = ipfsHash;
        emit HashStored(id, ipfsHash);
    }

    function getHash(uint256 id) public view returns (string memory) {
        return ipfsHashes[id];
    }
}

Enter fullscreen mode Exit fullscreen mode

Step 3: Uploading Files to IPFS
We'll use the ipfs-mini library to interact with IPFS. Create a new file called ipfsUpload.js and add the following code:

const IPFS = require('ipfs-mini');
const ipfs = new IPFS({ host: 'ipfs.infura.io', port: 5001, protocol: 'https' });

async function uploadFileToIPFS(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onloadend = async () => {
            const buffer = Buffer.from(reader.result);
            try {
                const response = await ipfs.add(buffer);
                const ipfsHash = response[0].hash;
                resolve(ipfsHash);
            } catch (error) {
                reject(error);
            }
        };
        reader.readAsArrayBuffer(file.data);
    });
}

Enter fullscreen mode Exit fullscreen mode

Step 4: Storing the IPFS Hash on the Ethereum Blockchain
To interact with the Ethereum blockchain, we'll use the web3.js library. Create a new file called blockchainInteraction.js and add the following code:

const Web3 = require('web3');
const contractAbi = require('./contractAbi'); // Replace with your contract ABI
const contractAddress = '0x123abc'; // Replace with your contract address

const web3 = new Web3('YOUR_QUICKNODE_URL');
const contract = new web3.eth.Contract(contractAbi, contractAddress);

async function storeHashOnBlockchain(ipfsHash) {
    const accounts = await web3.eth.getAccounts();
    const senderAddress = accounts[0];

    // Assuming you have a function named "storeHash" in your contract
    await contract.methods.storeHash(ipfsHash).send({ from: senderAddress });
}

Enter fullscreen mode Exit fullscreen mode

QuickNode and Chainlink Labs Establish Partnership To Help Provide Secure Blockchain Infrastructure

Step 5: Setting Up the Backend Server
We'll use Express and Multer to set up a simple backend server that allows file uploads. Create a new file called server.js and add the following code:

const express = require('express');
const multer = require('multer');

const app = express();
const upload = multer();

app.post('/upload', upload.single('file'), async (req, res) => {
    try {
        const file = req.file;
        const ipfsHash = await uploadFileToIPFS(file);
        await storeHashOnBlockchain(ipfsHash);
        res.status(200).send('File uploaded successfully!');
    } catch (error) {
        console.error(error);
        res.status(500).send('An error occurred while uploading the file.');
    }
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

Enter fullscreen mode Exit fullscreen mode

Step 6: Creating the Frontend Interface
Create an HTML file called index.html and add the following code:

<!DOCTYPE html>
<html>
<head>
    <title>IPFS File Upload</title>
</head>
<body>
    <h1>IPFS File Upload</h1>
    <form id="upload-form" action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file" id="file-input">
        <button type="submit">Upload</button>
    </form>

    <script src="frontend.js"></script>
</body>
</html>

Enter fullscreen mode Exit fullscreen mode

Step 7: Handling File Downloads
To download files from IPFS, we'll update the frontend JavaScript code. Create a new file called frontend.js and add the following code:

const IPFS = require('ipfs-mini');
const ipfs = new IPFS({ host: 'ipfs.infura.io', port: 5001, protocol: 'https' });

async function downloadFileFromIPFS(ipfsHash) {
    const data = await ipfs.cat(ipfsHash);
    // Process the downloaded file data as needed
}

// Enable users to download files from the frontend interface
// Assuming you have a list of IPFS hashes displayed on the frontend
const downloadButton = document.getElementById('download-button');

downloadButton.addEventListener('click', async () => {
    const selectedHash = 'YOUR_SELECTED_IPFS_HASH'; // Get the selected IPFS hash
    await downloadFileFromIPFS(selectedHash);
});

Enter fullscreen mode Exit fullscreen mode

Conclusion:
In this tutorial, we learned how to store files on IPFS and store their corresponding hashes on the Ethereum blockchain using QuickNode. We set up the development environment, created a smart contract, uploaded files to IPFS, stored the IPFS hash on the Ethereum blockchain, and created a frontend interface for file uploads and downloads. By leveraging the power of IPFS and Ethereum, you can build decentralized applications with robust file storage capabilities.

You can find the complete code and step-by-step instructions in the GitHub repository.

I'd love to connect with you on Twitter | LinkedIn | GitHub.

Top comments (0)