A Comprehensive Guide to Storing Files on IPFS and Ethereum with QuickNode
Dev-suite
Posted on June 29, 2023
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
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. 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.
Posted on June 29, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.