IPFS (Interplanetary File System) is a protocol and network designed to create a content-addressable p2p method for storing and sharing hypermedia on a distributed file system. In this article we are going to learn how to upload and download files to IPFS via command line and from JavaScript using RIF Storage client.

Brief intro

Let’s say you’re doing some research on aardvarks, you might start by visiting the Wikipedia page on aardvarks at:

https://en.wikipedia.org/wiki/Aardvark

When you put that URL in your browser’s address bar, your computer asks one of Wikipedia’s computers, which might be somewhere on the other side of the country (or even the planet), for the aardvark page.

However, that’s not the only option for meeting your aardvark needs! There’s a mirror of Wikipedia stored on IPFS, and you could use that instead. If you use IPFS, your computer asks to get the aardvark page like this:

/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Aardvark.html

IPFS knows how to find that sweet, sweet aardvark information by its contents, not its location. The IPFS-ified version of the aardvark info is represented by that string of numbers in the middle of the URL (QmXo…), and instead of asking one of Wikipedia’s computers for the page, your computer uses IPFS to ask lots of computers around the world to share the page with you. It can get your aardvark info from anyone who has it, not just Wikipedia.

And, when you use IPFS, you don’t just download files from someone else — your computer also helps distribute them. When your friend a few blocks away needs the same Wikipedia page, they might be as likely to get it from you as they would from your neighbor or anyone else using IPFS.

IPFS makes this possible for not only web pages, but also any kind of file a computer might store, whether it’s a document, an email, or even a database record.1

Getting started

Let’s find Aardvark Wikipedia’s file using the IPFS command line tool. Download it here. Once you have it run

tar xvfz go-ipfs.tar.gz
cd go-ipfs
./install.sh
ipfs init

This should take only minutes. Once you have the app let’s try getting the page.

Downloading files

Run in your terminal

ipfs cat QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Aardvark.html

This will output all the html content of the file in the console!

Uploading files

First I will create a simple file:

$ echo "hello ipfs" > foo
$ cat foo
hello ipfs

Now upload it:

$ ipfs add foo
added QmSoASxb8aNVGk3pNWpZvXEZTQKxjGeu9bvpYHuo5bP1VJ foo
 11 B / 11 B [==========================================] 100.00%

Now let’s get its content:

$ ipfs cat QmSoASxb8aNVGk3pNWpZvXEZTQKxjGeu9bvpYHuo5bP1VJ
hello ipfs

It’s awesome, and seems very easy to use. There’s a cool IPFS tutorial about how to use the command line tool in:

ipfs cat QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/quick-start

Hands on code

We are going to create a script that uploads an image to IPFS, then downloads it and displays it in the default image viewer.

Setup

  1. Let’s create a sample project

     mkdir ipfs-sample
     cd ipfs-sample
    

    We are going to use 3 packages:

    • fs to read and write files – The fs module provides an API for interacting with the file system in a manner closely modeled around standard POSIX functions 2
    • @rsksmart/rif-storage to connect to IPFS – Client library integrating distributed storage projects 3
    • open to open default image viewer – Open stuff like URLs, files, executables. Cross-platform 4
     npm i @rsksmart/rif-storage open
    
  2. Run IPFS Daemon. This will enable to use port 5001 to interact with IPFS file storage. In another terminal run

     ipfs daemon
    

Create the app

Let’s try getting the file we uploaded with the command line tool, the ‘hello ipfs’. Create a index.js file:

const RifStorage = require('@rsksmart/rif-storage')
const fs = require('fs')
const open = require('open')

const main = async () => {
  const storage = RifStorage.default(RifStorage.Provider.IPFS, { host: 'localhost', port: '5001', protocol: 'http' })
  const fileHash = 'QmSoASxb8aNVGk3pNWpZvXEZTQKxjGeu9bvpYHuo5bP1VJ'
  const retrievedData = await storage.get(fileHash)
  fs.writeFileSync(fileHash, retrievedData)
  open(fileHash)
};

main();

Now let’s try uploading a file. I’m going to upload my logo :D

I copy the file into the project folder and code:

const RifStorage = require('@rsksmart/rif-storage')
const fs = require('fs')
const open = require('open')

const main = async () => {
  const storage = RifStorage.default(RifStorage.Provider.IPFS, { host: 'localhost', port: '5001', protocol: 'http' })

  const file = fs.readFileSync('logo.png')
  const fileHash = await storage.put(file)
  console.log(fileHash)

  const retrievedData = await storage.get(fileHash)
  fs.writeFileSync(fileHash, retrievedData)
  open(fileHash)
};

main();

Run it with node index.js. You should find the image you uploaded popping up in your image editor.

Conclusion

We understood the basic operation of IPFS: it is a content-addressable file storage. We also understood, in broad terms, how it works.

We have operated with IPFS using the command line tool. We upload and download files.

We also made a JavaScript program, using the rif storage ipfs client, which allowed us to upload an image and view its content.

Now what?

There’s a lot more content to research on this exciting distributed file system.

References

  1. IPFS Docs
  2. fs
  3. @rsksmart/rif-storage
  4. open