🗜️Clevis + 📃 Dapparatus = 🔗🔥

Zero to Dapp, ASAP 😜


Clevis and Dappartus are my custom tools to build dapps as fast as possible. They help orchestrate the deployment of my smart contracts and provide quick access to commonly used components in React. I will dive into my process step-by-step from provisioning a server to mainnet deployment in the following article and then do a screencast that demonstrates the actions live:


Let’s start from nothing and fire up a fresh AWS EC2 instance from Ubuntu:

Image for post
Image for post

I’ll spin up a t2.small box which costs around $16 a month, but once the AMI is ready in AWS it could probably be scaled all the way down to a t2.nano.

We’ll need to open a few ports in a new security group too:

Port 22 (SSH) 
Port 30303 (Geth)
Port 3000 (Http/React)

To make SSHing easier, I’ll add an entry to my ~/.ssh/config

Host rinkeby
User ubuntu
Port 22
Hostname 18.191.175.177
IdentityFile ~/.ssh/MYKEYNAME.pem
TCPKeepAlive yes
ForwardAgent yes
IdentitiesOnly yes
StrictHostKeyChecking no

Now, with the box spun up, I can just ssh rinkeby and I’m in!

Let’s provision the box…

sudo apt-get update 
sudo apt-get dist-upgrade -y
sudo apt-get upgrade -y
sudo apt-get install build-essential python htop -y
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update && sudo apt-get install ethereum -y

Now let’s setup the rc.local so it syncs with the blockchain on boot…

Create a file called rc.local in your home directory with the contents:

#!/bin/sh -e
/usr/bin/geth version > /home/ubuntu/geth.log 2>&1
/usr/bin/geth --rinkeby --syncmode "light" --cache 512 --maxpeers 25 --datadir "/home/ubuntu/.geth" --rpc --rpcapi="db,eth,net,web3,personal" > /home/ubuntu/geth.log 2>&1 &
exit 0

(Note: replace — rinkeby with your chain of choice, remove for mainnet)

Then link that file over the top of the current rc.local and reboot:

sudo rm /etc/rc.local
sudo ln -s /home/ubuntu/rc.local /etc/rc.local
sudo chmod +x /etc/rc.local
sudo reboot

Now when the machine comes up and we ssh in, it should be syncing:

Image for post
Image for post
It will take a while before it really gets going and syncs up.
Image for post
Image for post
Once it starts getting blocks one at a time you are in sync and ready to go.
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
source ~/.profile
echo "export PATH=~/.npm-global/bin:\$PATH" >> .bashrc

Now let’s install clevis as a global bin:

npm install -g clevis

Now that clevis is a command we should be able to run from anywhere. Let’s create a new project starting with an empty git repo and build a simple Dapp.

cd ~
git clone https://github.com/austintgriffith/broadcaster-example-dapp.git
cd broadcaster-example-dapp
clevis init
npm start

This should bring up a webserver and if you navigate to the ip on port 3000 in a browser you’ll get a Dapp scaffolding up and ready:

Image for post
Image for post

Okay so technically we have a “Dapp”, but let’s actually #BUIDL something. Leave the development server up and running and create a new SSH session:

ssh rinkeby
cd ~/broadcaster-example-dapp
clevis create Broadcaster

This will create a blank smart contract that we can fill in with a few functions:

pragma solidity ^0.4.24;contract Broadcaster {  constructor() public {
emit Broadcast(now,"Contract Created!");
}
function broadcast(string output) public returns (bool){
emit Broadcast(now,output);
return true;
}
event Broadcast(uint timestamp, string output);}

Now let’s compile and deploy the contract using Clevis:

clevis compile Broadcaster

Okay, time to interface with the blockchain… once geth is in sync, we’ll want to create some accounts.

> clevis accounts
[]
> clevis new ""
> clevis balance 0
{ ether: '0', wei: '0', usd: 0 }

We have an account on the machine that can be used to deploy things, but first I’ll need to charge it up with some Eth:

> clevis balance 0
300000000000000000
> clevis unlock 0 ""
true

With our contract already compiled, we can now deploy it using account 0:

cd ~/broadcaster-example-dapp
clevis deploy Broadcaster 0

Compiling and deploying creates a few files of interest:

Image for post
Image for post

The Broadcaster.compiled is the file you upload to Etherscan to verify the source code. It will include all imports, etc:

Image for post
Image for post

Let’s interact with the contract first from the command line to make sure it performs like we think it will. We can use the Clevis explain command to see the contract’s interface:

Image for post
Image for post

Next, we can use the Clevis contract command to interact with the contract:

clevis contract broadcast Broadcaster 0 "Hello World"

This is telling clevis to run the broadcast command on the Broadcaster smart contract as account 0 with the arguments “Hello World”:

And we can test that our transaction worked by listing the events:

clevis contract eventBroadcast Broadcaster
Image for post
Image for post

Let’s go ahead and write a test to make sure that after we deploy a contract we can run the broadcast function and it will create an event with the correct string as the output.

Image for post
Image for post

Notice that the javascript in the test command looks exactly like our command line tests. This is an important part of Clevis. You can run things from the command line just to get a feel for them and then do the exact same thing in a mocha test when you are ready.

Now let’s run our test:

clevis test broadcast
Image for post
Image for post

Awesome. So our contract is written, compiled, deployed, and tested. The cool thing about Clevis tests is they are actually part of the overall orchestration; they do a lot of important actions. For instance, I could compile, test, deploy, and publish simply with clevis test full. See the tests/ directory to learn more about clevis testing and mocha.

Now let’s inject our contract into our Dapp and start interfacing with it from the React frontend code:

clevis test publish

Now we have published our contract which injects it into our Dapp:

Image for post
Image for post
Image for post
Image for post
Clevis injects important contract files like the abi, address, etc into the React app.

Now it’s time to bring in some Dapparatus components:

First, let’s throw the Contract Loader into the connectedDisplay:

Image for post
Image for post

Then, let’s fire up our React development server and see what we have so far.

cd ~/broadcaster-example-dapp
npm start

Navigate to the machine’s IP on port 3000:

http://18.191.175.177:3000/
Image for post
Image for post

Let’s dive into the console and look at what those components give us back:

Image for post
Image for post
MetaMask component keeps your state up-to-date with account, balance, block, network, etc.
Image for post
Image for post
Gas component keeps your state up-to-date with current gas prices.
Image for post
Image for post
ContractLoader component creates a “contracts” object in the React state to interface with the contracts.

We are connected to the Ethereum network, we know the current gas prices, and we have our contract interface ready to go. Rad.

To make transactions we will need to bring in the Transactions component:

Image for post
Image for post
Image for post
Image for post
Transactions component creates a tx() function for making transactions.

The Transactions component also creates a display in the bottom right that shows blocks and transactions loading with progress bars

Image for post
Image for post

Now let’s bring in a few more components for the user interface:

Image for post
Image for post
Address component and Button component for a nice little UI
Image for post
Image for post

Now let’s wire our button up to call the broadcast function on our Broadcaster smart contract just like we did in our tests:

Image for post
Image for post

We can fill in a broadcast string, hit Send, sign the transaction, and it’s off to the blockchain. Now that we are sending transactions to our contract, let’s bring in an “Events” component to track the events:

Image for post
Image for post

We’re almost done! Let’s see how this thing looks on a mobile sized window:

Image for post
Image for post

Oh, that’s no good. Call in the Scaler component to help us render our UI in a way that shrinks to smaller screens! To do this, wrap your UI elements with a <Scaler> </Scaler> and it will dynamically handle the scaling.

Image for post
Image for post

At this point of my Clevis build, I would usually move to a mainnet box and deploy to the main Ethereum chain, but I’ll skip that. Once my contracts are live, I deploy my React site up to S3 and put it behind Cloudfront for caching:

clevis build
clevis upload mysite.io
clevis invalidate CLOUDFRONTID

For more information on this process, check out my NiftiesVsNfties hack:

Thank you for checking out Clevis:

Go yell at me on Twitter: https://twitter.com/austingriffith

Learn more about me at: https://austingriffith.com


Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store