From Building Ethereum DApps by Roberto Infante

In this article I’ll give you a high-level overview of decentralized applications. I’ll explain in detail what they are, how they appear, what technology stack they are built on, and when it makes sense to build them.

Let’s start our journey!

A five-minute Dapp implementation

Now that you know what a Dapp is, it’s now time to get one little step further and get programming. In the rest of the article we’ll start building the smart contract of a custom cryptocurrency.

Let’s start building SimpleCoin, a basic cryptocurrency

Most Dapps are designed on functionality based on the exchange of cryptocurrency or tokens through rules encoded in one or more smart contracts. You’ll start to get a feel for Dapps programming by building SimpleCoin, a basic cryptocurrency which presents useful preliminary concepts about smart contracts and the Ethereum platform.

Since you haven’t installed any client for the Ethereum platform on your computer, you’ll be writing code on the Remix Solidity IDE (previously known as Browser Solidity) for now. This is an online tool which allows you to implement smart contracts in a high-level language called Solidity, which is similar to JavaScript, and run them on a local JavaScript VM that emulates the Ethereum Virtual Machine. It’s also possible, through this tool, to interact with real smart contracts deployed on the Ethereum network.

Open a web browser and go to: https://ethereum.github.io/browser-solidity/

You should see a screen like in figure 1.


Figure 1.   Screenshot of the Remix opening screen. You can see the code editor on the left and code execution panels on the right.


The left-hand side of the IDE is a code editor. The right-hand hand side contains various panels to run the code and interact with it.

In your first encounter with Solidity you’ll implement the simplest possible smart contract. If you think of a smart contract as the equivalent of a class in an object-oriented language, you’ll write a single class with only one-member field, one constructor and one method. Then you’ll run it and interact with it.

Enter the code of the following listing in the Remix editor, on the left side of the screen.

Listing 1   First implementation of SimpleCoin, a basic cryptocurrency

 
 pragma solidity ^0.4.0;                                ❶ 
  
 contract SimpleCoin {                                  ❷ 
  
     mapping (address => uint256) public coinBalance;   ❸ 
  
     function SimpleCoin() {                            ❹ 
  
         coinBalance[0x14723a09acff6d2a60dcdf7aa4aff308fddc160c]
               = 10000;                                 ❺ 
     }
  
     function transfer(address _to, uint256 _amount) {  ❻   
  
         coinBalance[msg.sender] -= _amount             ❼ 
         coinBalance[_to] += _amount                    ❽ 
     }
 }
 

❶   Pragma directive indicating the supported version of the Solidity compiler. The code supports a compiler later than 0.4.0 but earlier than 0.5.0.

❷   Defines a contract, which is similar to a class in other languages.

❸   Defines a state variable as a “mapping” between an address and an integer. A state variable is the equivalent of a member variable. A mapping is the equivalent to a hash table or hash map.

❹   Starts defining the contract constructor.

❺   Assigns 10000 SimpleCoin tokens to the coin account with address 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c at contract creation.

❻   Defines a function which moves a number of SimpleCoin tokens from the coin account of the function caller to a specified coin account.

❼   Decreases the coin balance of the message sender by the specified number of tokens. The special implicit property msg.sender represents the address of the sender of the transaction.

❽   Increases the coin balance by the specified number of tokens.

Let’s examine this code in detail. A contract, in Solidity, is a type similar to a class in any other language: it has state variables (such as coinBalance), a constructor (such as function SimpleCoin), functions (such as transfer), and events.

The coinBalance state variable is defined as a mapping. A mapping is a hash map, equivalent to a hashMap in Java, Dictionary in C# or dict in Python. In this example, the type of the key is an address, whereas the value is a uint256, an unsigned 256-bit integer. An address holds a 20-byte value and it can identify a specific smart contract account or a specific user account. An account, as we’ll see later in detail, is the sender or the receiver of a transaction. coinBalance therefore represents a collection of coin accounts, each holding a number of SimpleCoin tokens.

The transfer function is meant to move a number of SimpleCoin tokens from the coin account of the function caller to a specified coin account. In smart contract terminology, a function caller is the transaction sender. msg is a special implicitly defined variable that represents the incoming message. It has various properties, among which msg.sender represents the address of the sender of the transaction, who is the caller of transfer. The body of the transfer function is simple to understand. It’s subtracting the specified amount from the cash account associated with the function caller and adding the amount specified in the _amount parameter to the account associated with the address specified in the _to parameter. To keep this initial code simple, this implementation isn’t performing yet any boundary checks on the number of SimpleCoin tokens owned by the transaction sender, who, for example, shouldn’t be allowed to send more tokens than the owned ones.

At this point you should understand that our SimpleCoin “contract” is, in practice, a class with a constructor (SimpleCoin function), some state (coinBalance variable), and a method (transfer function). Table 1 gives a quick summary of the Solidity keywords you’ve come across.

Table 1. A summary of Solidity keywords met in the first code sample

Keyword

Explanation

contract

Type similar to class in any other language

mapping

Data structure similar to a hash table or hash map

address

20-byte value representing an Ethereum user account or contract account

uint256

Unsigned 256-bit integer

msg

Special variable representing an incoming message object

msg.sender

Property of the msg object representing the address of the message sender

Let’s run the contract

Move now to the right-hand side of the screen to instantiate the SimpleCoin contract.

If you’ve typed your code correctly, and there are no compilation errors, you should see the following buttons in the Contract panel: Publish, At Address and Create, as shown in figure 2. Ignore for the moment Publish and At Address. Focus your attention on Create, for the moment. By clicking this button, you’ll instantiate the SimpleCoin contract.

The contract is stored against an address identifying its location on the Ethereum blockchain. You can see it by clicking on the “Copy Address” button.


Figure 2.  Contract activation buttons. We’re focusing initially on Create.


Let’s interact with the contract

Now that the SimpleCoin contract has been instantiated you can perform simple operations against it: you’ll check SimpleCoin token balances and move tokens across accounts.

After clicking on Create, two new buttons appear: coinBalance and transfer, as shown in figure 3.


Figure 3.  SimpleCoin operations buttons. coinBalance is a getter of the coinBalance state variable and it’s a read-only operation. transfer allows to transfer the specified number of tokens to the indicated address.


The Remix IDE shows two types of buttons:

  • Blue buttons. They perform read operations against the contract, such as to check the value of state variables or call read-only functions.

  • Red buttons. They perform “write” operations against the contract, such as instantiating the contract through the constructor (Create) or, call functions which modify any state variables.

In our case, coinBalance is blue because it allows to read the coin balance associated with an address. transfer is red because by clicking it you alter the state of the contract, specifically by changing values contained in the coinBalance mapping state variable.

 Let’s check that the coinBalance associated with the address specified in the constructor has indeed the full initial supply of SimpleCoin you set at construction. Wrap the address with double quotes: “0x14723a09acff6d2a60dcdf7aa4aff308fddc160c”, enter it in the textbox and click coinBalance. Some output appears, and at its bottom you should see the expected number of SimpleCoin tokens you specified in the constructor: 10000.

0x14723a09acff6d2a60dcdf7aa4aff308fddc160c is the address of one of the five test accounts present on the Remix IDE. You can see them in the Transaction Origin dropdown list box on the top right of the screen. Although they aren’t fully visible on the screen, their full addresses are reported in table 2. (I have retrieved them by copying them one by one by clicking on the Copy Address icon next to the Account dropdown):

Table 2.  Remix test accounts whose full address is hidden behind the HTML

0xca35b7d915458ef540ade6068dfe2f44e8fa733c

0x14723a09acff6d2a60dcdf7aa4aff308fddc160c

0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db

0x583031d1113ad414f02576bd6afabfb302140225

0xdd870fa1b7c4700f2bd7f44238821c26f7392148

You can double check that the amount of SimpleCoin tokens associated with any address different from 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c is zero. For instance, enter the following address, wrapped with double quotes as you did earlier, in the coinBalance textbox: “0x583031d1113ad414f02576bd6afabfb302140225”. After clicking the button, you’ll see, as expected, an amount equal to 0.

Transaction costs and execution transaction costs

The designers of the Ethereum platform decided to charge for code execution for two main reasons: first, to encourage and reward participants (mainly the “miners”) who contribute to the platform by offering their computing power to process and validate transactions; and second, to discourage any malicious participant who’d deploy and execute nonsensical contracts with the only intent of damaging and disrupting the network, for instance with a Denial of Service attack.

Recapping, when you instantiated the contract, an amount of 10000 SimpleCoin tokens got assigned, as initial money supply, to the address starting with 0x14723a09. No other address owns any token yet, as summarized in table 3.

Table 3. Balance of each Remix test account after contract instantiation

Account address

Account balance

0xca35b7d915458ef540ade6068dfe2f44e8fa733c

0

0x14723a09acff6d2a60dcdf7aa4aff308fddc160c

10,000

0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db

0

0x583031d1113ad414f02576bd6afabfb302140225

0

0xdd870fa1b7c4700f2bd7f44238821c26f7392148

0

Now you can call the transfer function to move some tokens from account with address starting with 0x14723a09 to a different test account. Because the transfer function moves tokens from the account of its caller, the function must be called from the contract creator’s address starting with 0x14723a09. Pick this address from the Transaction Origin dropdown, then enter in the textbox of the transfer method the destination address (let’s pick, for example, the address starting with 0x4b0897b0) and a number of tokens to be transferred (for instance, 150 tokens). The values of these parameters should be separated by a comma:

  
 "0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db", 150
  

Now click the transfer button. Apart from the usual information on transaction and execution costs, there’s no actual return value from the function, as expected.

Check the number of tokens present in the contract creator’s address by clicking on the coinBalance button after having entered again the contract creator’s address (“0x14723a09acff6d2a60dcdf7aa4aff308fddc160c”) in the related textbox: the value is now 9850, as expected.

If you perform the same check on the destination address (“0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db”) you get: 150. All other addresses still have zero tokens, as summarized in Table 4:

Table 4. Balance of each Remix test account after a transfer operation

Account address

Account balance

0xca35b7d915458ef540ade6068dfe2f44e8fa733c

0

0x14723a09acff6d2a60dcdf7aa4aff308fddc160c

9,850

0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db

150

0x583031d1113ad414f02576bd6afabfb302140225

0

0xdd870fa1b7c4700f2bd7f44238821c26f7392148

0

As an exercise, you can try to transfer coins from the address starting with 0x4b0897b05 to a different address and recheck to see if the amounts are correct. While doing this, please don’t perform any “crazy” transactions, such as trying to move more coins than a certain address holds. As you know, in order to keep the code simple for the moment, you haven’t coded yet any boundary conditions.

Although the code you’ve written for this far is simple, your main objective, at this stage, is only starting to familiarize yourself with smart contracts, with the Solidity language, and with Remix. Hopefully you’ve achieved the objective! You now understand how contract instantiation works and how to interact with a contract from different accounts.

 SimpleCoin is still at the stage of an embryonic Dapp, however, and that’s where we will stop for now.

For more on DApps and Ethereum, read the entire first chapter of Building Ethereum ÐApps and see this slide deck.