Introduction to IPFS and Decentralized Storage.
Tags: javascript, blockchain, ipfs, react
Published: 2022-01-16 11:48:46

[IPFS](https://ipfs.io/) is InterPlanetary File System can be explained as peer-to-peer, decentralized storage network used to store and access files, websites, media, and applications.

It works by giving files a content address which we commonly refer to as a token rather than a location on the server.

The major feature of this technology is the fact that it’s a distributed file system which means your information is stored on multiple nodes and can be accessed using a generated address at any time.



![Centralized File System](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ptjef9veuysjnayx8tdk.png)
Centralized File System


![Decentralized File System](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vdzlfxi936mkgbc2pnlx.png)

Decentralized File system 

## Let’s discuss how it differs from the centralized NFS(Network File System)and https(hyper text transfer protocol)

  The network file system is the protocol that uses a network to access and retrieve data from multiple disks and directories. This explanation indicates the use of a server and a centralized administrator that distinguishes it from the IPFS whose procedure is to identify data by a hash reference/address. The address is shared among the users of the specific data.

Hyper text transfer protocol : The internet follows certain protocols to exchange information, such as the famous client-server protocol.  Using the http method, data has to be located based on it’s  directory/address on the specific server it’s on and once that server is down the data cannot be accessed. The ipfs solves all this by creating a cryptographic hash and also copies the address of data to multiple nodes so it won’t be affected by server crash. Also ipfs servers are free compared to http servers.


## **Building a dapp that uploads images to ipfs with React js**

The decentralized app will upload our image to ipfs servers. Requirement: Basic knowledge of react Js

We will be using the truffle unbox package, you might not need to download ganache or any local blockchain as we won't be hosting it on any blockchain server or using any smart contract.  

```bash
npm install -g truffle
truffle unbox react
npm install ipfs-http-client
```
This sets up a web3 dapp boilerplate for your work, it automatically sets up a dapp that connects to metamask plugin in your browser.

```bash
cd client && npm run start
```

Then navigate to src and restructure the app.js into this

```js
import React, { useState } from "react";
import { create } from "ipfs-http-client";

const App = () =>{
  return(
  <div className="App">
My dapp
  </div>
  )
}
```

Once you've done this you can use `npm run start` to start the program then we commence piecing it togeter. 

```js
    import React, { useState } from "react";
    
    const App = () =>{
  return(

  <div className="App">
                 <form>  
     <input type="file"/> //This  button collects the image for upload         
    <button type="submit">Submit</button>//Submit collected image to ipfs
        </form>

  </div>
  )
}



```
The first thing  we need is a file-input and a submit button.
 
The next thing is that we need to build functions for our upload. ``fileCapture`` gets the data in the ``<input type="file"/>``, The ``reader`` helps Javascrip read the contents of a file after with the onloadend function must be triggere to get a ready state.


```js
import React, { useState } from "react";

const App = () => {
    const [file, captureFile] = useState(null); // state for file upload

    const fileCapture = (e) =>{
        const data = e.target.files[0];
        const reader = new window.FileReader();
        reader.readAsArrayBuffer(data) 

        reader.onloadend = () =>{
          captureFile(Buffer(reader.result))
        }

        e.preventDefault()
      }

return (
   <div className="App">
    <form>
        <input type="file" onChange={fileCapture} />
          <button type="submit">Submit</button>
     </form>

   </div>
)
}
```
Here, we have the function to upload the image to ipfs by connecting to using ipsf gateways like Infura, Pinata and Fleek but we'll be using Infura because it's free and it gives read and write access.

Import create from the installed ipfs-http-client which will be used to connect infura with the function it returns a path or hash that we will add to our url. This url is mapped into an array that displays our images.

```js
import React, { useState } from "react";
import { create } from "ipfs-http-client";

const client = create("https://ipfs.infura.io:5001/api/v0");

const App = () => {
 const [url, setUrl] = useState([])

const handleSubmit = async (e) => {
        e.preventDefault();

        try{
          const created = await client.add(file);
          const url = `https://ipfs.infura.io/ipfs/${created.path}`;
          console.log(url)
          setUrl((nextUrl) => [nextUrl, url])
        }catch(error){
          console.log(error.message)
        }
      }

 return (
      <div className="App">
        <form onSubmit={handleSubmit}>
        <input type="file" onChange={fileCapture} />
          <button type="submit">Submit</button>
        </form>
     </div>
)
}
```
The next step is to render our images back in our UI this can be done using the following code:

```js
const App = () => {
return(
    <div className="App">
        <div className="display">
          {url.length !== 0 ? url.map((el) => <img src={el} alt={url} />)
          : <h3>Post Image to Ipfs</h3>}
        </div>
     </div>
)
}
```


**Here is the full code:**

```js
import React, { useState } from "react";
import { create } from "ipfs-http-client";


const client = create("https://ipfs.infura.io:5001/api/v0");

const App = () => {
    const [file, captureFile] = useState(null);
    const [url, setUrl] = useState([])

    const fileCapture = (e) =>{
        const data = e.target.files[0];
        const reader = new window.FileReader();
        reader.readAsArrayBuffer(data) 

        reader.onloadend = () =>{
          captureFile(Buffer(reader.result))
        }

        e.preventDefault()
      }

    
      const handleSubmit = async (e) => {
        e.preventDefault();

        try{
          const created = await client.add(file);
          const url = `https://ipfs.infura.io/ipfs/${created.path}`;
          console.log(url)
          setUrl((nextUrl) => [nextUrl, url])
        }catch(error){
          console.log(error.message)
        }
      }



    return (
      <div className="App"> 
                 <form onSubmit={handleSubmit}>  
     <input type="file" onChange={fileCapture} /> //This  button collects the image for upload         
    <button type="submit">Submit</button>//Submit collected image to ipfs
        </form>

        <div className="display">
          {url.length !== 0 ? url.map((el) => <img src={el} alt={url} />)
          : <h3>Post Image to Ipfs</h3>}
        </div>
      </div>
    );
}

export default App;
```
 

Then you run it with 

```bash
npm run start
```

It loads on your browser and you upload your picture. This way you've used the decentralized p2p file management system.


![IPFS Implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wvby4te7y7enf074x8ey.png)

IPFS has several uses and you can build various things on it, I'll love to get your feedback and questions in the comments