🛰 Decentralized Deployment

Publishing a 🏗 Scaffold-ETH build to IPFS + ENS

Austin Thomas Griffith
6 min readJul 10, 2020

This is [ part 2 of 2 ] from “🚀 Connecting ETH to IPFS”:

Assuming you have a local development environment setup from part 1, we’ll take that build and deploy it to an Ethereum test net and IPFS…

📡 Smart Contract

The first thing we want to deploy will be the smart contract. We will use Rinkeby in this example but the steps to go to mainnet Ethereum are the same. We need to edit our packages/buidler/buidler.config.js and change the defaultNetwork to rinkeby:

☢️ Warning: You will need to get your own Infura url, this one won’t work.

Next, we need to create a file named mnemonic.txt in packages/buidler. This file needs to contain a 12 word seed phrase that has enough ETH to pay the gas to deploy our contracts.

Try using this 🛠 eth.build to generate a random mnemonic, download it, and send it some Rinkeby funds:

Once you have funded a 12 word seed phrase and put it in the mnemonic.txt file in the packages/buidler folder and you have your buidler.config.js pointed at rinkeby, you are ready to deploy your contract:

yarn run deploy

⏱ It will take a bit longer than localhost because blocks are only mined every 15 seconds on this network.

Copy and paste your 📄 Attestor contract address into a search on rinkeby.etherscan.io and you should get something like this:

This address is also now published into our frontend. You could double check that with:

cat packages/react-app/src/contracts/Attestor.address.js

🧐 Take a second to think about how hard it would be to stop that contract now that we have deployed it. We can’t.

We will want our frontend to have a similar level of resilience.

🖼 Frontend

Your frontend will need one quick tweak. The localProvider is still looking at our local blockchain. Check the localProvider to be hardcoded to Rinkeby:

const localProvider = new ethers.providers.InfuraProvider("rinkeby",**YOURINFRUAID**)

OR

Use the environmental variable REACT_APP_PROVIDER. Either way, make sure everything comes up and is talking to the Rinkeby contract:

☢️ Warning: Before building the static frontend we will need to double check two thing. First, the packages/react-app/package.json should contain the setting:

"homepage":".",

And the packages/react-app/public/manifest.json file should contain:

"start_url": ".",

Now let’s tell React to build a static version of our app:

yarn run build

Traditionally, you would fire up yarn run surge or yarn run s3 or any other static site deployers, but we want to deploy something a little more… unstoppable. 🤖

🛰 IPFS

Just like in part 1, we will use Infura as our IPFS node. We will push our static build to Infura’s IPFS service with:

yarn run ipfs

This will take a little time to get all the assets pinned, but it will eventually output a CID:

Our app is now deployed to IPFS, but if we told users to visit our app on IPFS at QmPQ6Ek5ueit7D1aLJRNikdpuSLMt627b8oGXa1AWQi75L they probably wouldn’t have a very good time. Let’s make it a little friendlier with ENS:

🏷 ENS

We will want to register an ENS “.eth” domain to enable users easy access to our decentralized application. Visit https://app.ens.domains or your favorite alternative ENS manager site.

We can even just register a subdomain. Let’s register attestor.scaffold.eth.

☢️ Warning, the ENS manager is hard coding gas prices to 1 gwei like it’s 2017 so you will need to make sure you manually adjust your gas price with each transaction:

Make sure your domain has a resolve set:

You can just set your resolver to the public resolver if you don’t have one set yet.

Finally, enter the CID from our IPFS upload here prefaced with ipfs://:

Now when you visit your ENS name, your app should come up!

😎 Hard Mode

Just like on Ethereum, if we want to truly participate in the network we should install ipfs-go and run our own node:

wget https://github.com/ipfs/go-ipfs/releases/download/v0.6.0/go-ipfs_v0.6.0_darwin-amd64.tar.gz
tar -xvzf go-ipfs_v0.6.0_darwin-amd64.tar.gz
cd go-ipfs
bash install.sh
ipfs daemon

Now, any where you are using:

const ipfs = ipfsAPI({host: 'ipfs.infura.io', port: '5001', protocol: 'https' })

You can switch to:

const ipfs = ipfsAPI({host: 'localhost', port: '5001', protocol: 'http' })

You could even spin up your own pinning server in the cloud: follow the install steps, open up port 5001, edit the ~/.ipfs/config and change any 127.0.0.1/tcp/5001 to 0.0.0.0/tcp/5001. Then you can use this machine’s ip address for the ipfsAPI() host.

We can now update the packages/react-app/ipfs.js to start pinning to our own node and it will be a lot faster!

yarn run ipfs
So fast! 🐇

🔖 IPNS

If we had to update our ENS record every time we pushed a change to our site, iterating would get expensive and time consuming. Let’s put a level of abstraction between IPFS and ENS called IPNS.

Now that we have our own IPFS node up and running, we also have our own key pair that can participate on the network. That means we can “publish” signed IPFS content and get a static IPNS for our ENS entry.

Uncomment the block of IPNS code in packages/react-app/ipfs.js:

Now we can deploy our code to IPFS and publish the name to IPNS:

yarn run ipfs

We can now visit that gateway url to see our app:

🚀 ENS + IPNS

Instead of entering an IPFS content hash, try registering an IPFS name with the ENS app:

This allows you to update your IPNS with each new IPFS hash as your content changes but the ENS doesn’t need to be updated on-chain each time!!!

http://ipfs.scaffold.eth.link should now display our Attestor app:

🧐 Conclusion

That’s the TL;DR. You’ll have to dig into the code to understand more, but this example dapp should get you started! There are so many cool things you can build with Ethereum + IPFS and I’m super excited to see what you are thinking about.

💬 We started a Scaffold-ETH & IPFS HackFS support chat, please join us if you have questions or comments!

📚 If you would like to learn more, there are a handful of tutorials and example builds in the scaffold-eth repo.

🙏 Thanks

I want to give a huge shout out to Adam Fuller 🐦. Without him this just wouldn’t be done in time. He has put in a handful of nights and weekends to help me progress 🏗 scaffold-eth with both ⛽️ GSN stuff and this IPFS+NFT stuff:

🔭 If you want to see how Adam and I are using this starter dapp to build a full product, follow the 👩‍🎨 Nifty.Ink dev branch and look for updates coming soon!

--

--