A glimpse into how to build an Ethereum DApp

cxr
Rock and Null
Published in
6 min readJun 26, 2018

Blockchain is hot right now. And you know what’s hotter? Ethereum. I have recently experimented with Ethereum by making a simple DApp (Distributed App). I want to contribute back to the community …… by making another (kind of) tutorial on how to create a DApp.

The objective of this post will not be to guide you step-by-step on how to build a DApp. I won’t explain everything here; I will link to a lot of other places that explain each part better. Still, I believe it’s good high-level overview on how / what is needed to start building Ethereum DApps.

Glossary

If you want to get a high-level understanding of what blockchain is, dedicate 15 minutes and watch these excellent videos (it’s part 1 & 2, and then you can play practically with the introduced concepts).

Ethereum is a “blockchain-based distributed computing platform” that allows you to create distributed programs called smart contracts. Now, if you make this contract to act like the back-end of a website, and you put a front-end to interact with this contract you get a DApp (distributed app).

These contracts are written in a language called Solidity that has a C-like syntax (although you can write smart contracts in other languages, this is the most popular). To actually use these smart contracts, you need to deploy them to the Ethereum network by paying some Ether, the native cryptocurrency of Ethereum.

Intro

You used to have to manually keep track of where you deployed a contract, but new frameworks like Truffle and Embark are making developing and deploying smart contracts way easier.

To create my sample DApp I used the Truffle framework because it seems to be more popular (i.e. more StackOverflow posts) and had better tutorials available. Embark seems really decent, but being a complete newbie in the field, I went with the popular choice.

My sample DApp is called dWIP (decentralised work in progress) and you can use it to publicly keep track on the work you are doing for your side-project (partly inspired by wip.chat). As shown in the GIF, you just enter the task you are working on and it’s added to the list. Then you can share this page with the users of your side-project to keep them updated about the progress :)

Truffle provides the Ethereum Pet Shop tutorial which I highly recommend and I based my sample DApp on.

Backend

As mentioned earlier, the backend of this web app is the smart contract. To get a taste of Solidity, this how the contract for my sample dapp looks like:

pragma solidity ^0.4.6;  // 1.

contract Dwip {

struct Task {
string text;
uint timestamp;
}

struct AddressData { // 2.
Task[] taskArray;
string addressName;
}

mapping(address => AddressData) addressDataMap; // 3.

function appendTask(string taskText) public returns (uint length) { // 4.
Task memory t = Task(taskText, block.timestamp);
return addressDataMap[msg.sender].taskArray.push(t);
}

function getTaskCountAddr(address addr) public constant returns (uint length) { // 5.
return addressDataMap[addr].taskArray.length;
}

function getTaskCount() public constant returns (uint length) {
return getTaskCountAddr(msg.sender);
}

function getTaskAtIndexAddr(address addr, uint index) public constant returns (string value) { // 6.
return addressDataMap[addr].taskArray[index].text;
}

function getTaskAtIndex(uint index) public constant returns (string value) {
return getTaskAtIndexAddr(msg.sender, index);
}
  1. Instruction for the Solidity compiler denoting the language version
  2. The data that we hold for each address. A different address should be used in this case for every different side-project
  3. The mapping from address to the data we hold.
  4. Create a new WIP task (i.e. a new row) calling this function. Notice that the function return type is declared at the end.
  5. Get how many WIP tasks (i.e. rows) are stored for a specific address. Notice the constant keyword that indicates that the function does not make any changes to storage (i.e. saving data). It’s just read-only (and cheaper to call).
  6. There are 2 versions for each function, one that uses the msg.sender address and one that takes the address as a parameter. This for linking to different address (i.e. side-projects) with a GET parameter (e.g. /dwip?addrr=0xABCD)

(To write a contract and be able to iterate and interact with it, you can use Remix, the official online Ethereum IDE.)

Truffle provides an easy way to write tests in Solidity to call these methods and verify that they work as indented (and that will not break in the future).

pragma solidity ^0.4.17;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Dwip.sol";

contract TestDwip {
Dwip dwip = Dwip(DeployedAddresses.Dwip());

function testAppendTask() public {
uint returnedLength = dwip.appendTask("hello");

Assert.equal(returnedLength, 1, "Incorrect task length.");
}

function testGetCount() public {
uint returnedCount = dwip.getTaskCount();

Assert.equal(returnedCount, 1, "Incorrect task count.");
}

function testGetCountAddr() public {
uint returnedCount = dwip.getTaskCountAddr(this);

Assert.equal(returnedCount, 1, "Incorrect task count.");
}

function testGetTaskAtIndex() public {
string memory expected = "world";
dwip.appendTask(expected);
string memory returnedTask = dwip.getTaskAtIndex(1);

Assert.equal(returnedTask, expected, "Incorrect task text.");
}

function testGetTaskAtIndexAddr() public {
string memory expected = "beyond";
dwip.appendTask(expected);
string memory returnedTask = dwip.getTaskAtIndexAddr(this, 2);

Assert.equal(returnedTask, expected, "Incorrect task text.");
}
}

These are not the traditional unit tests in the sense that the state is not reset every time. To actually run these test, you can use a local private blockchain with Ganache:

Frontend

When you are done writing the contract, you will have to call these methods. The frontend of a DApp consists of conventional web technology (i.e. javascipt, html, css). When you deploy a contract on a network (main or test network), you get an address to be able to call it. Truffle makes it really easy to call a smart contract by keeping track of where (i.e. the address) is deployed. For instance, for my sample DApp the code to add a new WIP task is similar to:

web3.eth.getAccounts(function (error, accounts) {  // 1.

var account = accounts[0]; // 2.

App.contracts.Dwip.deployed().then(function (instance) { // 3.
return adoptionInstance.appendTask(taskText, {from: account}); // 4. }).then(function (result) {
return App.fetchWips(); // 5.
}).catch(function (err) {
console.log(err.message);
});
});
  1. Web3 is the javascript library to communicate with Ethereum nodes.
  2. Select the first available account from the wallet.
  3. Truffle is keeping track of the address the contract is given when deployed on a network.
  4. When you have an instance of the deployed contract, you can call methods. Note that the method called here is not constant so an account to be charged is provided as an argument.
  5. The result of the method call is returned. Here is unused.

Wallet

To make a transaction with an Ethereum smart contract you need a wallet. DApps are just smart-contracts-as-web-backends and an in-browser wallet is needed to perform transactions. The most popular (and the only one I know) in-browser wallet is called Metamask for Chrome, Firefox and Opera. Extensive instructions here on how to set it up.

Backend deployment

When you want to make your DApp available for the world, you need to deploy it to the Ethereum main net or a test net. Like the names are suggesting, to deploy to the main net real ether (i.e. money) is needed. I have only tried deploying to a test net (there are multiple test nets, like Rinkeby and Ropsten) where no real money is needed (you get fake money from a faucet). To deploy to a network you will need to run a client on your machine and download the whole blockchain transaction history on your machine (that means you will need a lot of space, and depending on your connection a lot of time). To deploy to Rinkeby follow the instructions here. Note that there is a way to deploy without downloading the whole blockchain on your machine, but I have not tried it.

Frontend deployment

You can deploy the frontend (i.e. HTML, CSS, Javascript files) to a regular web server (like I did) or go fully decentralised and host your files on a P2P network like IPFS. Follow the instructions in the “Deploy the application online with IPFS” section for IPFS hosting.

Conclusion

Blockchain and the decentralised web revolution in general, is exciting and it evolves really fast. New frameworks, like Truffle, removes the major pain points from Ethereum development, but it’s still early so keep an eye (as I will do) for further developments in the field!

--

--