#BUIDLGUIDL — 0x0: Clevis & Dapparatus

A toolset for rapid dApp development and prototyping

Austin Thomas Griffith
7 min readOct 25, 2018

If you are thinking about getting into decentralized application development or moving over to Clevis & Dapparatus to speed up your dApp workflow, this is a great step-by-step tutorial to get you started!

We had this idea to make a video series exploring Ethereum development from the ground up. A no-dumb-questions environment where we would be free to explore and #buidl.

* disclaimer, I did not make this up. Credit to @theflyinghutch & @KamesCG

We’re no magicians… but we are a guild of healers, bards, damage dealers, and screen sharers! We want to start from a very approachable base and #buidl up. If you have questions, ask!

Clevis

We are going to use Clevis as our orchestration tool. Check out the repo to see all the installation options. The best way to use it is installing it globally, but some systems have a hard time with the dependencies. The easiest way to fire up a Clevis environment is with Docker. We’ll point our container at an empty directory in our home folder (~/test-app/). It will take a while to download and compile:

docker run -ti --rm --name clevis -p 3000:3000 -p 8545:8545 \
-v ~/test-app:/dapp austingriffith/clevis

Note: It doesn’t matter *where* you run this docker command. Your Dapp code will be available wherever you point the “-v ~/test-app” part.

(~ is your home directory and it will make whatever folder you name it)

Once your container comes up, you will be presented with a command prompt.

Let’s check the current version of Clevis. We will want to do that with two different commands. clevis version and clevis test version should both return similar things, but you are testing both the CLI and the NPM package.

🗜️ Clevis:/dapp 🗜️ clevis version
{ clevis: '0.0.94', web3: '1.0.0-beta.36' }
🗜️ Clevis:/dapp 🗜️ clevis test version
#version()
{ clevis: '0.0.94', web3: '1.0.0-beta.36' }
✓ should get version
1 passing (36ms)0

This container will bring up our local blockchain and a development web server too! Navigate a browser to localhost:3000 and unlock MetaMask:

Not much to see here. You may be on a different network than Rinkeby, that’s okay.

You can switch MetaMask to the local network (included in the Clevis container). Click on your network in MetaMask and click Custom RPC:

New RPC URL:

http://localhost:8545

Hit save and select the new network from the menu:

You probably won’t have any fake ETH yet, let’s fix that. From your Clevis command prompt, let’s list the accounts that come with our test Ethereum blockchain:

clevis accounts
>>> ACCOUNTS
Reading Accounts...
[ '0xe7aFe9e667F1dfbFA01c74414e715077f6e92b26',
'0x4b845F37e9D681Bc2CA1024941F11c00C0C6c397',
'0x53fBB36e7f6B2cF02D8683a2978DEDe1EC25E4Ba',
'0xB069d7632bEbd8a686e955E2CdeD8Fae4c96C847',
'0x8D50bA3481BF92eb5CD7030D4F1318fa3AE47170',
'0x9597eA00167766EEe706A13Dcaeefb3440A93EEE',
'0xE56Ff1300bF4D9fB449ec9a19517C1c0D24d6fC9',
'0xe9099bE13f8604B50fb66ffe08fA2b3555383f82',
'0xD617C220D5a856aA87D9dc2dc6F39c1Cbc2D936B',
'0x9A01c0d91bB62cD266E1c00a3dbdCdBd3c60321c' ]

Wow, there are a bunch, let’s check the balance of that first one:

clevis balance 0xe7aFe9e667F1dfbFA01c74414e715077f6e92b26
>>> BALANCE
null '100000000000000000000'
{ ether: '100', wei: '100000000000000000000', usd: 28423.83 }

Homie is loaded. Okay, let’s transfer some to our main account in MetaMask. You can copy your address by clicking the account in MetaMask:

Now in the console let’s use the sendTo command to send ETH from account 0:

clevis sendTo 0.1 0 *YOURADDRESSHERE*

You should see your balance update in the frontend:

There are a lot of other commands built into Clevis and they are all listed in the repo. You can also run:

clevis help

The web3 library has a lot of utilities built in and Cleivs extends those to make them easy to use from the CLI or in your tests. Let’s try out a couple so you have some extra tools in your toolbox for developing dApps.

Converting Wei

There are no floating points so when you see an Ethereum balance it will often look like this:

99595105456200000000

That is really hard to read, so you can run something like:

clevis fromwei 99595105456200000000 ether
99.5951054562

Also, many smart contract take in values in Wei instead of ether. So to convert an amount like 0.001 ETH you can do:

clevis towei 0.001 ether
1000000000000000

Text to Hex and back

Many smart contracts hold small strings in the bytes32 datatype. You will need to input that data as hex and when it comes back out you will want to convert it back to readable text:

clevis tohex "Hello World!"
0x48656c6c6f20576f726c6421

And then on the way back you can:

clevis fromhex "0x48656c6c6f20576f726c6421"
Hello World!

Hash

If you ever need to hash some data from the CLI or in a test, Clevis abstracts that from the web3 library too:

clevis sha3 "Hello World!"
0x3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0

Dapparatus

Dapparatus is a set of commonly used React components used to build web3 applications. After a few hackathons you will probably find yourself using the same handful of components and Dapparatus is meant to handle those for you. The goal is for the developer to focus on their app and not wrestling with blockchain components.

<MetaMask />

<Metamask
onUpdate={(state)=>{
console.log("metamask state update:",state)
if(state.web3Provider) {
state.web3 = new Web3(state.web3Provider)
this.setState(state)
}
}}
/>

The <MetaMask /> component syncs up all the important account, network, and block information into your React state. Notice there is an onUpdate() hook that fires every time a new block is mined or your account balance changes.

<Gas />

<Gas
onUpdate={(state)=>{
console.log("Gas price update:",state)
this.setState(state,()=>{
console.log("GWEI set:",this.state)
})
}}
/>

The <Gas /> component connects to the EthGasStation API to load up-to-the-minute gas prices into your React state so your transactions will go through quickly and efficiently.

<Transactions />

<Transactions
account={account}
gwei={gwei}
web3={web3}
block={block}
avgBlockTime={avgBlockTime}
etherscan={etherscan}
onReady={(state)=>{
//loads in tx() function
// use to send transactions: tx(contracts.YOURCONTRACT.YOURFUNCTION(),GASLIMIT)
console.log("Transactions component is ready:",state)
this.setState(state)
}}
/>

The <Transactions/> component displays each block with a predicted time it should be mined. It also displays your transactions with links to Etherscan so you can see the progress. This component exposes a tx() function to make transacting with the blockchain as simple as possible and makes a familiar callback when the transaction finishes. It also will orchestrate a lot of the meta transactions but we’ll get to that in later chapters.

<ContractLoader/>

<ContractLoader
web3={web3}
require={path => {return require(`${__dirname}/${path}`)}}
onReady={(contracts)=>{
console.log("contracts loaded",contracts)
this.setState({contracts:contracts})
}}
/>

The <ContractLoader/> component loads your contracts in as the are published from Clevis. Notice you also have an onReady() hook for running actions when your contracts are ready.

<Events />

<Events
config={{hide:false}}
contract={contracts.Nifties}
eventName={"Create"}
block={block} <-------- current block number!
id={"_id"}
filter={{_owner:account}}
onUpdate={(eventData,allEvents)=>{
console.log("EVENT DATA:",eventData)
this.setState({events:allEvents})
}}
/>

Parsing through blockchain events can be a pain in the butt. This component tries to abstract that away for you. It will even filter and index events then call onUpdate() for each event it finds so you can keep your React state up-to-date.

<Address />

<Address
{...this.state}
address={contracts.Stories._address}
/>

The <Address /> component shows an address and links to Etherscan. It can also show the balance that address holds with an indenticon. Other options availableible to hide and show different parts of it too.

<Button />

<Button color={"green"} size={"2"} onClick={()=>{
//do some transaction on button click
tx(contracts.SomeContract.someFunction(someArgument),(receipt)=>{
//when the transaction goes through you'll have a receipt here
})
}}>
Write
</Button>

Styled similar to MetaMask buttons, this is just a nice component to have in terms of style.

<Blockie />

Bonus points, this is a Boba Fett blockie I mined.
<Blockie
address={"0x06d59402d0b0ffd63f3660a5fe837f620c3e9df2"}
config={{size:10}}
/>

Blockies, or Identicons, are used to visually inspect an account. These should only be used to quickly identify if you have the right account and that you didn’t ‘fat finger’ it. Don’t blindly trust them in the wild.

<Scaler />

<Scaler config={{startZoomAt:1000,origin:"50px 50px",adjustedZoom:1.3}}>
<img style={{position:"absolute",left:10,top:10,maxHeight:120,margin:10}} src={titleImage}/>
</Scaler>

The <Scaler/> is mainly meant to help a dApp be mobile responsive in a brute force kind of way. You can set the max and min size of something and it will scale in between based on the width of the browser.

If you want to learn more about Dapparatus, there are plenty of docs in the repo. It is open source, of course, and any contributions to the code are very welcome! Help us make it the component library for web3! If you want to learn more about Clevis, the full repo is here.

Awesome. We are set to start to hacking! Continue on to #BUIDLGUIDL — 0x1: guidlcoin or take a deeper dive into Clevis & Dapparatus.

If you are interested in building dApps powered by meta transactions with Clevis & Dapparatus, I’m hosting a workshop at Devcon in Prague Oct 31 at 3:30PM in the Coquelicot room.

--

--