Skip to content

Instantly share code, notes, and snippets.

@brodo
Created March 8, 2018 14:17
Show Gist options
  • Save brodo/511ba958f3ceda8d4e925a8cb16b000f to your computer and use it in GitHub Desktop.
Save brodo/511ba958f3ceda8d4e925a8cb16b000f to your computer and use it in GitHub Desktop.
IPFS Workshop

[TOC]

Getting started with IPFS

:::info The first part of this workshop is pretty much the same as IPFS - Install and IPFS - Getting Started. :::

Download and Install IPFS

Download go-ipfs. Choose amd64 or click the button on the top right.

Linux & Mac

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

Run ipfs help and check if it works!

Windows

After downloading, unzip the archive, and move ipfs.exe to a location like C:\Program Files\IPFS.

Add this folder to your PATH variable by doing the following:

Either look for path in Windows search or to to System Preferences -> System and Security -> System -> Change Settings -> Advanced -> Environment Variables

German: Systemsteuerung -> System und Sicherheit -> System -> Einstellungen aendern -> Erweitert -> Umgebugnscariablen

Open Powershell and run ipfs help and check if it works!

2. Initialise IPFS and try it out

$ ipfs init
initializing ipfs node at /Users/jbenet/.go-ipfs
generating 2048-bit RSA keypair...done
peer identity: Qmcpo2iLBikrdf1d6QU6vXuNb6P7hwrbNPW9kLAH8eG67z
to get started, enter:

  ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme

Note the hash there may differ. If it does, use the one you got. Now, try running:

$ ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme

:::info Try our $ ipfs cat on more files. :::

Running the IPFS Deamon

$ ipfs daemon
Initializing daemon...
Swarm listening on /ip4/10.23.42.1/tcp/4001
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip4/192.168.1.111/tcp/4001
Swarm listening on /ip6/2003:dc:f3d1:c301:18cd:4d6f:eec:17ab/tcp/4001
Swarm listening on /ip6/2003:dc:f3d1:c301:cc33:c17c:a54a:18dc/tcp/4001
Swarm listening on /ip6/::1/tcp/4001
Swarm listening on /p2p-circuit/ipfs/QmVNAh2uL34zPJQNfhUKuNgMeCVeZFkziZwWf2CbrSHRdg
Swarm announcing /ip4/10.23.42.1/tcp/4001
Swarm announcing /ip4/127.0.0.1/tcp/4001
Swarm announcing /ip4/192.168.1.111/tcp/4001
Swarm announcing /ip6/2003:dc:f3d1:c301:18cd:4d6f:eec:17ab/tcp/4001
Swarm announcing /ip6/2003:dc:f3d1:c301:cc33:c17c:a54a:18dc/tcp/4001
Swarm announcing /ip6/::1/tcp/4001
API server listening on /ip4/127.0.0.1/tcp/5001
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
Daemon is ready

Open a new terminal and keep the daemon running in the background. Under Windows, allow it to access all networks.

In the new terminal type:

$ ipfs swarm peers
/ip4/1.69.99.42/tcp/4001/ipfs/QmQtzAQk9YCw7rcHV1ZNneF74MNFtrCnBjQFh6Wz7MSWrg
/ip4/101.230.198.106/tcp/15821/ipfs/QmXK2H7tPG8quN9wABSU5YaCvokapvy3ae2hVR4NJbzWVS
/ip4/103.234.143.151/tcp/4001/ipfs/QmPa5t3WTtrvZnqCebymNWKW2Mz3kzoyHY6nQifxq25839
/ip4/103.254.67.162/tcp/7000/ipfs/QmTazMgRkmCbtMgtnfChyWQ9ApbtJuZxgbtJaL75NrSX6v
/ip4/104.131.10.96/tcp/4001/ipfs/QmQQVXUUTrNxWv2bbCvV7R34H3qwKuj6Hyv8U8TDzq3ZZb
/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
/ip4/104.155.40.139/tcp/4001/ipfs/QmXHdKgabDcdciZvbyTT7t7h4fbTmdHM3F3Z7he7jhHbb1
/ip4/104.155.77.104/tcp/4001/ipfs/QmaLcVjoAi9QnHytpe3ehoWNBNqARRmJR4P18Qfyadpyki
[...]

Downloading an image from the network

$ ipfs get /ipfs/QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ/cat.jpg

Adding a textfile to the network

Create a text file. Add it to IPFS.

$ ipfs add textfile.txt
added QmQvWenhpWccD74JGoigHWtFtBsHY2HwnLV2mAXutjZKFP textfile.txt
graph LR

QmQvWenhpWccD74JGoigHWtFtBsHY2HwnLV2mAXutjZKFP --> textfile.txt

Loading

Open your browser at the url https://ipfs.io/ipfs/<your hash>. For example https://ipfs.io/ipfs/QmQvWenhpWccD74JGoigHWtFtBsHY2HwnLV2mAXutjZKFP

Since you have the IPFS daemon running, you can also reach the same file under http://127.0.0.1:8080/ipfs/<your hash>. For example http://localhost:8080/ipfs/QmQvWenhpWccD74JGoigHWtFtBsHY2HwnLV2mAXutjZKFP

Web UI

We also have a web console you can use to check the state of your node. On your favourite web browser, go to:

http://localhost:5001/webui


Building a Static Website

Download a prepared website

Download the static website from this GitHub Repo.

If you like, you can make some changes to the website.

Publish your website in IPFS

Add the folder to IPFS

$ ipfs add -r ipfs-workshop-website
added QmQhiDRtMpNpcR3SNgRAMGqNHHGAeaFwVhQP5gWwh6NQzt ipfs-workshop-website/hasi_logo.png
added Qma1zdq3j5apKMXtXY1YCAku7wzJzyVJKK3ZvLEAQvJgKS ipfs-workshop-website/index.html
added QmTqZhR6f7jzdhLgPArDPnsbZpvvgxzCZycXK7ywkLxSyU ipfs-workshop-website/ipfs_logo.svg
added QmYUNE2uJvNuREfBXHQ1Zam4F4PbG2upxXQssjySxmGRzn ipfs-workshop-website/style.css
added Qmf9hHqdXmdQB9c898ViEuVcP1LD8QBe36ugAjvvm4n9vD ipfs-workshop-website

Navigate to the IPFS hash of the folder (the last hash in the listing)! For example https://ipfs.io/ipfs/Qmf9hHqdXmdQB9c898ViEuVcP1LD8QBe36ugAjvvm4n9vD/

You now have a static website.

graph TD
    Qmf9hHqdXmdQB9c898ViEuVcP1LD8QBe36ugAjvvm4n9vD --by content--> WS(ipfs-workshop-website)
    WS --by name--> hasi_logo.png(hasi_logo.png)
    WS --by name--> index.html(index.html)
    WS --by name--> ipfs_logo.svg(ipfs_logo.svg)
    WS --by name--> css(style.css)
    
Loading

Next, change something in the site and do ipfs add -r on the folder again:

$ ipfs add -r ipfs-workshop-website
added QmQhiDRtMpNpcR3SNgRAMGqNHHGAeaFwVhQP5gWwh6NQzt ipfs-workshop-website/hasi_logo.png
added QmWjgPKuutESkH69m5f8Mk32cciRGv4nkJFgEtccmkTpTw ipfs-workshop-website/index.html
added QmTqZhR6f7jzdhLgPArDPnsbZpvvgxzCZycXK7ywkLxSyU ipfs-workshop-website/ipfs_logo.svg
added QmYUNE2uJvNuREfBXHQ1Zam4F4PbG2upxXQssjySxmGRzn ipfs-workshop-website/style.css
added QmTib9NFDq4A911PGjUZF5gSYLSJKCBZviiPXXSmCRKZH3 ipfs-workshop-website

I changed index.html so the hash for that and for the folder changed!

IPNS - Changeable sites

As we have seen, all content in IPFS is static, because it is content addressed via hashes. If you wan to make changes to your site over time (e.g. post new content), you need IPNS. The same IPNS address can point to different IPFS hashes over time.

To publish your website on IPNS:

$ ipfs name publish QmTib9NFDq4A911PGjUZF5gSYLSJKCBZviiPXXSmCRKZH3                                                                                                                                         
Published to QmVNAh2uL34zPJQNfhUKuNgMeCVeZFkziZwWf2CbrSHRdg: /ipfs/QmTib9NFDq4A911PGjUZF5gSYLSJKCBZviiPXXSmCRKZH3

The address this was published to is your IPFS 'peer id' and will not change when you publish something else.

graph TD
    
    QmVNAh2uL34zPJQNfhUKuNgMeCVeZFkziZwWf2CbrSHRdg --> QmTib9NFDq4A911PGjUZF5gSYLSJKCBZviiPXXSmCRKZH3
    QmTib9NFDq4A911PGjUZF5gSYLSJKCBZviiPXXSmCRKZH3 --> WS(ipfs-workshop-website)
    
Loading

Let's go to that website http://localhost:8080/ipns/<address> e.g.: http://localhost:8080/ipns/QmVNAh2uL34zPJQNfhUKuNgMeCVeZFkziZwWf2CbrSHRdg

You can also publish something else under the same adress. For example the cat image from earlier:

$  ipfs name publish QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ/cat.jpg
Published to QmVNAh2uL34zPJQNfhUKuNgMeCVeZFkziZwWf2CbrSHRdg: /ipfs/QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ/cat.jpg
graph TD
    
    QmVNAh2uL34zPJQNfhUKuNgMeCVeZFkziZwWf2CbrSHRdg -.old link.-> Qmf9hHqdXmdQB9c898ViEuVcP1LD8QBe36ugAjvvm4n9vD
    QmVNAh2uL34zPJQNfhUKuNgMeCVeZFkziZwWf2CbrSHRdg --new link--> QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ/cat.jpg
    Qmf9hHqdXmdQB9c898ViEuVcP1LD8QBe36ugAjvvm4n9vD --> WS(ipfs-workshop-website)
    QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ/cat.jpg --> cat(cat.jpg)
    
Loading

You can also give your website a proper domain if you have one.

Building a Web Based Markdown Viewer with JS-IPFS

Connecting to IPFS via Javascript

Create a new directory a file called index.html inside of it. Put the following content into index.html:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8"> 
	<title>IPFS Markdown viewer</title>
</head>
<body>
	<h1>IPFS Markdown viewer</h1>
</body>
	<script src="https://unpkg.com/ipfs/dist/index.min.js"></script>
	<script src="https://cdn.jsdelivr.net/npm/ipfs/dist/index.min.js"></script>
	<script type="text/javascript">
		const node = new Ipfs();
		node.on('ready', () => {
		  console.log("IPFS READY")
		});
	</script>
</html>

Open the file in your browser and open the Javascript Console. You should see IPFS READY.

Downloading a file

Change the content script tag to this:

const node = new Ipfs();
node.on('ready', () => {
  function printMarkdown(err, file){
    if(err){
        console.log(err);
    }
    console.log(file);
  }
  var hash = 'Qmb5RvXk5zo1ZEm7c14eMGoej6guHroiWtC7uBUALz9Acy';
  node.files.cat(hash, printMarkdown);
});

The result you get in the console should look something like this:

Uint8Array(88) [ 35, 32, 73, 80, 70, 83, 32, 87, 111, 114, … ]

We have just downloaded the file with the hash Qmb5RvXk5zo1ZEm7c14eMGoej6guHroiWtC7uBUALz9Acy' using Javascript!

files.cat passes a byte array to our printMarkdow function. We need to convert that to a string:

function printMarkdown(err, file){
    function printMarkdown(err, file){
        if(err){
            console.log(err);
        }
        var str = file.toString();
        console.log(str);
    }
}

Reload the page and check out the markdown string!

Adding interaction

Now that we have the IPFS part done, we need to add some UI. Add a input where the user can paste a hash, a button to retreive the file and a div for showing it.

<body>
	<h1>IPFS Markdown viewer</h1>
	
	<input type="text" name="hash-field">
	<button>Get File</button>
	<div></div>
</body>

We also need to update our Javascript. This version does not jet show the output in the div

const node = new Ipfs();
node.on('ready', () => {
    var button = document.querySelector('button');
    var input = document.querySelector('input');
    button.addEventListener('click', downloadMarkdown);

    function downloadMarkdown(){
        var hash = input.value;
        node.files.cat(hash, printMarkdown);
    }

    function printMarkdown(err, file){
        if(err){
            console.log(err);
        }
        var str = file.toString();
        console.log(str);
    }
});

To actually parse and display the markdown, we use the marked library. Add it to the bottom of the page. Your new site should look like this:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8"> 
	<title>IPFS Markdown viewer</title>
</head>
<body>
	<h1>IPFS Markdown viewer</h1>
	
	<input type="text" name="hash-field">
	<button>Get File</button>
	<div></div>
</body>
<script src="https://unpkg.com/ipfs/dist/index.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ipfs/dist/index.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.17/marked.min.js"></script>

<script type="text/javascript">
	const node = new Ipfs();
	node.on('ready', () => {
	    var button = document.querySelector('button');
	    var input = document.querySelector('input');
	    var markdownDiv = document.querySelector('div');
	    button.addEventListener('click', downloadMarkdown);

	    function downloadMarkdown(){
	        var hash = input.value;
	        node.files.cat(hash, printMarkdown);
	    }

	    function printMarkdown(err, file){
	        if(err){
	            console.log(err);
	        }
	        var str = file.toString();
	        markdownDiv.innerHTML = marked(str)
	    }
	});
</script>
</html>

Publishing to IPFS

The last thing we need to do it add our HTML file to IPFS and we have a nice "dApp". How to do it is described above.

:::success Happy Hacking. :::

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment