A Comprehensive Guide to Storing Files on IPFS and Ethereum with QuickNode
Tags: blockchain, webdev, programming, tutorial
Published: 2023-06-29 17:33:42

## 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

```
**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];
    }
}

```
**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);
    });
}

```
**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 });
}

```

> [QuickNode and Chainlink Labs Establish Partnership To Help Provide Secure Blockchain Infrastructure] (https://blog.quicknode.com/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');
});

```
**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>

```
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);
});

```
Conclusion:
In this tutorial, we learned how to store files on IPFS and store their corresponding hashes on the Ethereum blockchain using [QuickNode](https://www.quicknode.com/). 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] (https://github.com/Dev-suite/ipfs-ethereum-tutorial.git).

I'd love to connect with you on [Twitter](https://twitter.com/Dev_suite) | [LinkedIn](https://www.linkedin.com/in/devsuite01/) | [GitHub](https://github.com/Dev-suite).