Building dapps on Ethereum – part 4: decentralised hosting using Swarm

The more I research and develop on Ethereum the more realize that Ethereum is the web we wanted to build yesterday, and the new web we are building today. There’s a lot of talk about Ether’s US dollar price and market cap, but the underlying technology is often forgotten about. That’s why I’m writing this series and in this part we’ll talk about a lesser known part of Ethereum, namely its decentralised storage platform called Swarm. We will use this to host our dapp.

Before we begin

If you haven’t already, I would recommend you to read the previous posts in this series:

Throughout this blog post series we will use sample code from the Iron Doers project which is a quite simple concept briefly described in a practical example of using blockchains and the project’s whitepaper.

Why decentralised hosting?

As we have decentralised the computational aspects of our application with smart contracts on the blockchain, it makes perfect sense to decentralise the actual hosting of the HTML and JS parts of our dapp as well. Because why should you trust a single host to serve your dapp? That single host will then get the ability to track all users of your dapp.

Further, decentralised hosting provide some other practical benefits like resistant to DDoS attacks and censorship while maintaining zero-downtime. Remember that AWS S3 outage that took out half the Internet? Or the DDoS attack against Wikileaks when publishing information about certain US presidential candidates? These are the kinds of events that would not have happened, should the content have been published in a decentralised way.

Introduction to Swarm

First of all, at the time of writing Swarm is still in proof-of-concept mode and should not be considered ready for production use.

Swarm is a new content distribution protocol that you access via bzz:/<name>. It’s not that different from http://<name> except that the content is not served from one central place. What’s unique with Swarm (compared to Bittorrent or IPFS) is that you can “upload and disappear” because peers will be incentivized to distribute your content by earning Ether (although as of writing this part is not yet fully developed for Swarm).

One temporary problem with Swarm is that regular web browsers don’t yet understand the bzz protocol. This is why Swarm comes with a HTTP gateway. A Swarm gateway is a HTTP server that can serve any content from the Swarm platform.

For example, the Swarm website is available at bzz:/theswarm.eth/. But you can also use this public gateway:

You can’t bind traditional DNS names to your Swarm content. I hear you ask — why is that? Because DNS is centralised! What we instead need are browsers that understand this new decentralised web called Ethereum :)


We will install and set up a single Swarm instance locally, for testing purpose.

The reference implementation of the Swarm protocol is written in Go and it’s included in the [Go Ethereum client][geth] called geth. In this guide we will use the cutting edge of both geth and swarm which means we’ll compile them from source! So if you previously installed geth with brew we need to uninstall it to not mix up the binaries!

$ brew uninstall ethereum && brew untap ethereum/ethereum

The compilation steps are documented in the Swarm installation guide. It’s not as daunting as it sounds. The Go language (or rather, its compiler) makes this really easy. The only important thing is that you have your Go environment correctly set up before compiling. Below are the summarized steps:

Install Go:

$ brew install go git

Create your Go project directory and export that as an environment variable. You might have to re-open your terminal for the changes to take full effect.

$ mkdir -p ~/Projects/Go
$ echo "export GOPATH=$HOME/Projects/Go/" >> ~/.bash_profile
$ echo "export PATH=$PATH:$GOPATH/bin" &gt;&gt; ~/.bash_profile
$ source ~/.bash_profile

Next, clone and compile the source code:

$ mkdir -p $GOPATH/src/
$ cd $GOPATH/src/
$ git clone
$ cd go-ethereum
$ go get
$ go install -v ./cmd/geth
$ go install -v ./cmd/swarm

Verify your installation by checking the version output. It should look something like this:

$ geth version
Version: 1.6.7-unstable
$ swarm version
Version: 1.6.7-unstable

Building and hosting your dapp

We are building on the project directory structure we defined in part 2 of this series. You can also see the example project repository on Github.

First, let’s make sure we have newly compiled contracts and javascript files in the tree:

$ truffle compile --all
$ npm run build

Second, we need to start geth, enter the console, set up at least one account and start mining:

$ geth --datadir ./chain init ./genesis.json
$ geth --datadir ./chain --rpc --rpcapi="db,eth,net,web3,personal" console

List your existing accounts:

> personal.listAccounts

If you don’t have any accounts yet, create a new one:

> personal.newAccount();

Unlock the account (for as many seconds as you need it) and start mining:

> personal.unlockAccount("MAINACCOUNT", "THEPASSWORD", 9999);
> miner.start(1)

Once the miner is running we can deploy our contracts to the blockchain:

$ truffle migrate --reset

Running and uploading to Swarm

First, we need to start Swarm using one of our accounts on the blockchain. You will be asked to enter the password to unlock the account for Swarm:

$ swarm --bzzaccount MAINACCOUNT \
  --datadir ./chain/ \
  --ens-api ./chain/geth.ipc \
  --verbosity 4 \
  --maxpeers 0

Once Swarm is running, in a different terminal tab we will upload our public dapp files to Swarm. Copy the hash that’s returned for the directory.

$ swarm --recursive --defaultpath www/index.html up www/

Now you can access the files you uploaded through your local HTTP gateway at:


Success! Our dapp is now hosted on the decentralised Swarm platform!

Ethereum Name Service

In the next blog post we will go through how to set up Ethereum Name Service (ENS) locally to register a more human friendly name, instead of e.g. bzz:/c777819a8eaa98d61615d94be49cd3bfaa95a2ccbe0225a3c3cf354777f33c0f/.

Continue reading