|
From Building Ethereum ÐApps 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!
|
Save 37% on Building Ethereum ÐApps. Just enter code fccinfante into the discount code box at checkout at manning.com.
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. If you are interested in finding out more about decentralized exchanges you might want to read more about the white label decentralized exchange.
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. Those that are engaged in cryptocurrency trading and investing may want to expand their base of knowledge to include things like how to short Bitcoin to protect them in the event of a market crash. Traders and investors within the cryptocurrency market will try their best to improve and expand their investments, opting for a digital wallet or an exchange service similar to monedero in order to protect their earning in case of market crash. You’ll start to get a feel for Dapps programming by building SimpleCoin, a basic cryptocurrency that presents useful preliminary concepts about smart contracts and the Ethereum platform. If you want to be fully equipped to start building your very own cryptocurrency it is important that you are aware of the current state of play in the field. These Bitcoin Statistics in 2020 would be an excellent resource for anyone in this position.
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.
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.
If you want to learn more about the book, check it out on liveBook here and see this slide deck.