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: swarm-gateways.net/bzz:/theswarm.eth/
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
swarm which means we’ll compile them from source! So if you previously installed
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:
$ 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" >> ~/.bash_profile $ source ~/.bash_profile
Next, clone and compile the source code:
$ mkdir -p $GOPATH/src/github.com/ethereum $ cd $GOPATH/src/github.com/ethereum $ git clone https://github.com/ethereum/go-ethereum $ cd go-ethereum $ go get github.com/ethereum/go-ethereum $ 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 Geth Version: 1.6.7-unstable ...
$ swarm version Swarm 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.
$ 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 ["MAINACCOUNT", "ANOTHERACCOUNT"]
If you don’t have any accounts yet, create a new one:
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/ HASH
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.