Rapid Ethereum Dapp Development with Next.js

Adrian Li
4 min readNov 22, 2017

--

Ethereum Dapp development with Truffle + Solidity + Next.js

tl;dr — I made a boilerplate project for Ethereum Dapp/Smart Contract development called Truffle-Next. It’s a Truffle Box and you can get it here.

Update: I’ve since rewritten the Truffle Box to use a Render-Prop pattern instead of the HOC pattern described below. Nevertheless, it should be straight-forward to use and understand.

The first time I touched Ethereum was back in 2013, when Alethzero was the hottest thing ever. My friends all thought Ethereum was super fringe at the time, and unfortunately I stopped paying attention to it.

Fast-forward to 2017.

Ethereum, smart contracts, and dapps are all the rage. Suddenly everyone is saying that this is sure to be the world of tomorrow. Well okay I thought, it’s been 3 years, making dapps should be super simple now, right?

Yes and no.

We no longer have to use geth on the command line for everything and write Solidity without syntax highlighting. We also have Truffle to help us write our contracts and test them to make sure we can integrate them with our frontends. But when it comes to tying this all together, things are not so straight-forward.

Warning: The following is not a tutorial. This is simply an introduction to the skeleton project that I am sharing as a Truffle Box.

Truffle Boxes

Truffle boxes are basically skeleton Truffle projects packaged with a frontend. You can take a look at some of them here.

There is a Truffle Box with a Create-React-App built-in. But upon closer inspection it just isn’t built for rapid development. The app itself is ejected and the frontend is mixed in with all the files from the Truffle project. Maybe I’m not the brightest lightbulb, but it was a little confusing for me.

Next.js

Zeit’s amazing React.js framework, Next.js is one of the best things to have hit the Javascript community since… dare I say Mootools?

It’s as simple as Create-React-App, but it doesn’t eject into a huge mess if you need to customize a couple things here and there. In fact, it’s the only way I write React apps nowadays.

Combining the two

Well the logical thing at this point is to combine the two. So I did. I wrote a Truffle Box that allows you to run the following:

truffle unbox adrianmcli/truffle-next

And immediately (and by immediately, I mean immediately after it downloads everything, hah) you will have a Truffle project with a sample smart contract as well as a Next.js app that interfaces with the smart contract.

Go to the repo and follow the instructions if you want to do this yourself while following along.

The Smart Contract

The smart contract that comes with the skeleton is simple:

pragma solidity ^0.4.18;contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint) {
return storedData;
}
}

You can do two things:

  1. Set a value.
  2. Get a value.

That’s it. There’s nothing more I can say about it.

The Next.js App

The Next.js app is a bit more complex and it consists of three pages:

  • index.js — This is a barebones Next.js page. It links to other pages which are web3-enabled. In your dapp, this can be a landing page.
  • accounts.js — This is a page listing the accounts returned from Web3. This file demonstrates the basic use of the withWeb3 higher-order component (HOC).
  • dapp.js — This is a barebones demonstration dapp that utilizes the withWeb3 HOC, but also makes calls to the contract. More specifically, it stores a value and gets a value.

And this is what the accounts.js page looks like:

The above code demonstrates very simply that wrapping your component with the withWeb3 HOC auto-magically injects some props into your component (in this case, only accounts is being used).

For a more detailed example, check out the dapp.js file:

There are two buttons and a balance display. The first button sets 5 as the value, and the second button simply retrieves the current value in the deployed contract.

On line 10, you can see that contract.set() is called with a value of 5 (while specifying that the command is being called from the first account, i.e. accounts[0]).

On line 16, you can see that contract.get.call() is called in a similar fashion. The resulting response is not a native Javascript number, so we call toNumber() on it to cast it back to a Number. From there, we simply set it as our component state and it renders to our app.

Note that contract and accounts conveniently come from our this.props thanks to our higher-order component :).

Conclusion

So that’s it! I hope this was at least slightly useful for you. I didn’t mean for this to be a tutorial or anything, I just wanted to share my Truffle Box.

If you felt this was interesting, please give me a CLAP. Feel free to leave comments and submit issues and PRs as well. Cheers.

--

--