This Ethereum tutorial is mainly about setting up a development environment, writing and compiling a smart contract.
What is Ethereum
Ethereum is an open source public blockchain platform with smart contract capabilities. Through its dedicated cryptocurrency Ether, it offers a decentralized Virtual Machine (the “Ethereum Virtual Machine”) to process peer-to-peer contracts.
The concept of Ethereum was first proposed in 2013-2014 by programmer Vitalik Buterin, inspired by Bitcoin, and loosely referred to as “the next generation of cryptocurrencies and decentralized application platforms”. It was developed in 2014 through ICO crowdfunding. Ether is now the second most valuable cryptocurrency after Bitcoin.
What is the Ethereum blockchain?
The Ethereum blockchain has two main components:
-
Data storage: Every transaction in the network is stored on the blockchain. When you deploy a contract, it’s a transaction. When you perform the contract function, it’s another transaction. All of these transactions are open for everyone to see and verify. This data can never be tampered with. To ensure that all nodes in the network have the same copy of data and that no invalid data is written to the blockchain, Ethereum uses an algorithm called proof of work to secure the network.
-
Code: In terms of data, blockchain is about storing transactions. In the ethereum world you can write logic/application code (aka smart contracts) in a language called Solidity. The code is then compiled into Ethereum bytecode using the Solidity compiler, and the bytecode is deployed to the blockchain (there are a few other languages for writing contracts, but Solidity is by far the most used and relatively easy option). So ethereum doesn’t just store transaction data, it stores and executes smart contract code.
It is easy to understand that the function of the Ethereum blockchain is to store data and code and execute code in EVM (Ethereum Virtual Machine).
The basics to prepare
In order to develop Ethereum, you should have a basic understanding of the following languages/technologies:
- Familiarity with an object-oriented language (e.g. Python, Java, Go)
- HTML/CSS/Javascript
- Basic command-line interactions such as Linux shell commands
- Understand the basic concepts of database
To decentralize Ethereum applications, a Decentralized JavaScript library attached to Web3. js can be added to JavaScript frameworks, such as React. Angular, Vue, etc.
Example: an Ethereum voting application
In the Ethereum tutorial example, we will build a simple decentralized voting application. A decentralized application is one that exists on more than one centralized server. There are so many copies of the application running on hundreds of thousands of computers in the network that downtime is almost impossible. You will build a voting app, where you can initialize candidates to participate in the election and vote on the candidates, and those votes will be recorded on the blockchain. You’ll go through the whole process of writing voting contracts, deploying to and interacting with the blockchain. You’ll learn what a contract is and what it means to deploy and interact with a contract on a blockchain.
In essence, a blockchain is like a distributed database that maintains an ever-growing list of records. If you’re familiar with relational databases, you know that there are many rows of data in a table. Now, batch the data (say, 100 rows per batch) and connect the batches for each batch. You can form a blockchain! In a blockchain, each batch of data is called a block, and each row in that block is called a transaction.
Now that you have a basic understanding of Ethereum, we can start building voting DApps. This will strengthen your understanding of Ethereum and give you a glimpse of what ethereum can do.
Ethereum development environment setup
Linux
The example is the learning environment setup in Ubuntu 16.04. All you need to do is successfully install NodeJS and NPM and proceed to the next step of the project.
We support the Ethereum tutorial by installing ganache and web3 packages via NPM. We also need to install Solc to compile the contract.
Here is the installation process:
$ sudo apt-get update
$ curl -sL https://deb.nodesource.com/setup_7.x -o nodesource_setup.sh $ sudo bash nodesource_setup.sh $ sudo apt-get install Nodejs $node --version v7.4.0 $NPM --version 4.0.5 $mkdir -p Ethereum_Voting_dapp /chapter1 $cdEthereum_voting_dapp /chapter1 $NPM install ganache-cli [email protected] solc $node_modules/.bin/ganache-cliCopy the code
If the installation is successful, run the command node_modules/.bin/ganache-cli and you should see the following output.
Ganache CLI v6.0.3 (Ganache - core: 2.0.2) Available Accounts = = = = = = = = = = = = = = = = = = 0 (0) x5c252a0c0475f9711b56ab160a1999729eccce97 (1) 0x353d310bed379b2d1df3b727645e200997016ba3 (2) 0xa3ddc09b5e49d654a43e161cae3f865261cabd23 (3) 0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
(4) 0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
(5) 0xda695959ff85f0581ca924e549567390a0034058
(6) 0xd4ee63452555a87048dcfe2a039208d113323790
(7) 0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
(8) 0xba7ec95286334e8634e89760fab8d2ec1226bf42
(9) 0x208e02303fe29be3698732e92ca32b88d80a2d36
Private Keys
==================
(0) a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
(1) 17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
(2) ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
(3) 68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
(4) 9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
(5) 6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
(6) c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
(7) cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
(8) c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
(9) eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
HD Wallet
==================
Mnemonic: cancel better shock lady capable main crunch alcohol derive alarm duck umbrella
Base HD Path: m/4460 '/'/ 0'/0/{account_index} Listening on localhost:8545Copy the code
For testing purposes, Ganache creates 10 accounts by default, each with 100 aether. If you don’t know what an account is, just think of it as a bank account where you deposit money (Ether is the money/currency in the Ethereum ecosystem). You need to use this account to create transactions and send/receive aether.
MacOS
If you haven’t already installed Homebrew, follow the instructions at https://brew.sh/ to install it. Homebrew is a package manager that helps us install all the other software we need for development. Follow the instructions below to install all other required packages.
$brew update $brew install nodejs $node --version v7.10.0 $NPM --version 4.2.0 $mkdir -p ethereum_voting_dapp/chapter1 $cdEthereum_voting_dapp /chapter1 $NPM install ganache-cli [email protected] solc $node_modules/.bin/ganache-cliCopy the code
We installed ganache and web3 packages through NPM. We also need to install Solc to compile the contract.
If the installation is successful, run the command node_modules/.bin/ganache-cli and you should see the output shown on the right.
Ganache CLI v6.0.3 (Ganache - core: 2.0.2) Available Accounts = = = = = = = = = = = = = = = = = = 0 (0) x5c252a0c0475f9711b56ab160a1999729eccce97 (1) 0x353d310bed379b2d1df3b727645e200997016ba3 (2) 0xa3ddc09b5e49d654a43e161cae3f865261cabd23 (3) 0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
(4) 0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
(5) 0xda695959ff85f0581ca924e549567390a0034058
(6) 0xd4ee63452555a87048dcfe2a039208d113323790
(7) 0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
(8) 0xba7ec95286334e8634e89760fab8d2ec1226bf42
(9) 0x208e02303fe29be3698732e92ca32b88d80a2d36
Private Keys
==================
(0) a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
(1) 17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
(2) ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
(3) 68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
(4) 9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
(5) 6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
(6) c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
(7) cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
(8) c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
(9) eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
HD Wallet
==================
Mnemonic: cancel better shock lady capable main crunch alcohol derive alarm duck umbrella
Base HD Path: m/4460 '/'/ 0'/0/{account_index} Listening on localhost:8545Copy the code
For testing purposes, Ganache creates 10 accounts by default, each with 100 aether. If you don’t know what an Ethereum account is, just think of it as a bank account where you deposit money (Ether is the money/currency in the Ethereum ecosystem). You need to use this account to create transactions and send/receive aether.
Windows
- Install Visual Studio Community Edition. If you choose a custom installation, you should at least install Visual C++ (currently VS 2017)
- Install the Windows SDK for Windows
- Install Python 2.7 if you haven’t already, and be sure to add it to the environment variable PATH
- Install Git if you haven’t already installed it and added it to PATH
- Install OpenSSL. Make sure you select the correct installation package and only install the full version (not the light version). You must install OpenSSL to the recommended installation location – do not change the installation path
- Download and install Node V8.1.2. Version V6.11.0 with VS2017 is not recommended
- Run NPM install ganache-cli [email protected] solc
Solidity Contracts
Now that ganache is installed and running, we’ll start writing our first Ethereum smart contract.
Contracts will be written using the Solidity programming language. If you are familiar with object-oriented programming, learning to write contracts in Solidity should be simple. We’ll write a contract called Voting (think of the contract as a class for object facing programming languages) that has the following:
- A constructor that initializes some candidates.
- A method for voting (add 1 to the number of votes)
- A method that returns the total number of votes received by a candidate
When you deploy the contract to the blockchain, the constructor is called, and only once. Unlike the Web world, where code overwrites old code every time it is deployed, contracts deployed on a blockchain are immutable, meaning that if you update the contract and deploy again, the old contract still exists on the blockchain, and the data still exists. The new deployment will create a new instance of the contract.
Pragma solidity ^ 0.4.18; contract Voting { mapping (bytes32 => uint8) public votesReceived; bytes32[] public candidateList;function Voting(bytes32[] candidateNames) public {
candidateList = candidateNames;
}
function totalVotesFor(bytes32 candidate) view public returns (uint8) {
require(validCandidate(candidate));
return votesReceived[candidate];
}
function voteForCandidate(bytes32 candidate) public {
require(validCandidate(candidate));
votesReceived[candidate] += 1;
}
function validCandidate(bytes32 candidate) view public returns (bool) {
for(uint i = 0; i < candidateList.length; i++) {
if (candidateList[i] == candidate) {
return true; }}return false; }}Copy the code
Copy the code on the right into a file called Voting. Sol and save it under the chapter1 directory.
Code and explanation
- Line 1. We must specify which version of the compiler the code will compile with
- Line 3. Mapping is equivalent to an associative array or dictionary, and is a key-value pair. The key of mapping votesReceived is the name of the candidate and is of type Bytes32. The value of the mapping is an unassigned integer that stores the number of votes.
- Line 4. In many programming languages, you can simply get all candidate names through votesreceived.keys. However, there is no such method in solidity, so we have to manage a separate array of candidates, candidateList.
- Line 14. Note that votesReceived[key] has a default value of 0, so you don’t need to initialize it to 0, just increment it by 1.
You’ll also notice that each function has a visibility specifier (such as public in this case). This means that functions can be called from outside the contract. If you don’t want anyone else to call this function, you can make it private. If you do not specify visibility, the compiler will throw a warning. Recent improvements have been made to the Solidity compiler to catch if users forget to mark private functions so that private functions can be called externally. You can see all the visibility specifiers here.
You’ll also see a view modifier on some functions. It is usually used to tell the compiler that the function is read-only (that is, the blockchain state is not updated when the function is called). All modifiers can be seen here.
Compiling smart contracts
We will compile the code using the SolC library installed in the previous section. If you remember, web3JS is a library that lets you interact with the blockchain via RPC. We will use this library to deploy contracts in the Node console and interact with the blockchain.
First, run Node in the terminal to access the Node console, initialize the Web3 object, and query the blockchain for all accounts.
Make sure ganache is already running in another window at the same time
To compile the contract, load the code from Voting. Sol and bind it to a string variable, then compile the contract as follows.
$ node
In the node console
> Web3 = require('web3')
> web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
> web3.eth.accounts
['0x5c252a0c0475f9711b56ab160a1999729eccce97'
'0x353d310bed379b2d1df3b727645e200997016ba3'
'0xa3ddc09b5e49d654a43e161cae3f865261cabd23'
'0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'
'0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'
'0xda695959ff85f0581ca924e549567390a0034058'
'0xd4ee63452555a87048dcfe2a039208d113323790'
'0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'
'0xba7ec95286334e8634e89760fab8d2ec1226bf42'
'0x208e02303fe29be3698732e92ca32b88d80a2d36']
> code = fs.readFileSync('Voting.sol').toString()
> solc = require('solc')
> compiledCode = solc.compile(code)
Copy the code
When you have successfully compiled the contract and printed the compiledCode object (you can see the content by typing the compiledCode directly into the Node console), you will notice that there are two important fields that you must understand:
- 1.com piledcode.contracts [‘:Voting’]. Bytecode: This is the compiled bytecode of Voting. Sol. It is also the code to be deployed on the blockchain.
- 2.com piledcode.interface [‘:Voting’]. This is an interface or template for contracts (called ABI definitions) that tells the user what methods are in the contract. You will need this ABI definition whenever you want to interact with any contract in the future. You can see more about the ABI here.
The tutorial is based on the DAPP development tutorial from Uizhi. If you can’t wait for the blog update, you can also visit the Ethereum tutorial directly.