Ethereum

Learn how to work with Ethereum, the cryptocurrency for Smart Contracts, a revolutionary technology, home of the cryptokittens, and BTC's main competitor.

Ethereum

If you would like to become a Blockchain developer, sooner or later, you will work with Ethereum. It is the second-largest cryptocurrency at the moment. According to coinmarketcap, its market capital is half the size of Bitcoin and twice the size of Ripple, the third-largest cryptocurrency. Ethereum, like Bitcoin, is a Blockchain solution that provides sharing coins' features. So, why did it become so popular? All the small differences between Ethereum and the first cryptocurrency make it so popular — the smart contracts, quickly mined blocks and low fees.

What is Ethereum?

Like Bitcoin, Ethereum is a Blockchain solution. The general functional principle is the same — currency owners can exchange the funds by sending the transactions which are broadcasted with the decentralized Blockchain. But a couple of differences make Ethereum so special

Blocks are Mined More Often

Every block in mined in approximately 10 minutes in Bitcoin. In Ethereum, it happens 4-5 times per minute. Thus, making microtransactions, ordering pizza, or paying for goods does not require one to wait for 10 minutes until the transaction receives the first confirmation.

Smaller Blocks

In Bitcoin, the block size is currently specified at 1MB. The Ethereum block size is calculated in a totally different way and depends on the complexity of transactions included in this block. Every block can have a complexity of around 8,000,029 Gas. Every transaction has its own complexity called the Gas and calculated from the code, smart contracts, and information that the transaction includes. Let’s say that a single, basic transaction has a complexity of 21,000. There may be 380 simple transactions in the block (Bitcoin can contain about 2000). However, if any of those transactions included in this block is more complex and requires more Gas, the total number of transactions will be lower.

Smart Contracts

The Smart Contracts are what makes Ethereum so unique. Imagine an ordinary contract in real life. It says that if a person A delivers some goods, products or work, the other contracting party B will pay. In the programmers' world, we would say that the payment will be done if all conditions are met. In Ethereum, we can write such a contract in the primitive scripting language called Solidity, which is executed by Ethereum Virtual Machine.

Mining Rewards

In Bitcoin, the Miner is rewarded by 12.5 BTC now, and this number will decrease every year. Ethereum rewards every mined block by 5 ETH, and this number is constant — that adds up to around 11,5 million ETH per year. Moreover, the Miner is rewarded with the Gas from contracts (like the fee in Bitcoins), and references to 2 recent uncles with 1/32 of a block reward — 0.15625 ETH per uncle.

Smart Contracts

The Smart Contracts are the most important feature provided by Ethereum. What is Smart Contract? In a real world, the contracts between parties are executed after all conditions have been met. After that, the service provider receives payment. Ethereum provides a basic programming language in which you can write your own conditions. If all of them are fulfilled, the contract will automatically execute.

The difference between Bitcoin and Ethereum is that Ethereum supports more sophisticated conditions and methods in Smart Contracts than Bitcoin. The options are limited only by the imagination, which can be extremely creative. In late 2017, one of the Smart Contracts blocked the Blockchain for a few days and was generating about 10% of transactions in Ethereum for a couple of weeks. What was it about? Virtual Cats.

The CryptoKitties is a Smart Contract that allows users to collect or buy and breed digital cats. Each Cat is one-of-a-kind and 100% owned until you sell it. And the price is double the price that you paid for the cat. It goes down until somebody will buy the cat. Thus, Ethereum allows users to write games with the Smart Contracts.

Solidity

Solidity is a contract-oriented programming language for implementing Smart Contracts. It was influenced by C++, Python, and JavaScript and is designed to target the Ethereum Virtual Machine.

Solidity is quite similar to JavaScript in my opinion. Easy to learn and execute. But there is one thing that is really, really hard during the development process — testing. Compared to other applications I used to develop, here, maintenance is impossible. Therefore, top-level quality is a must-have. If a Smart Contract is published to the Blockchain, it can never be changed. Every change requires a new Smart Contract. If you find a bug in your code, it is a huge decision to make — leave it or move all users to a new Smart Contract.



Digital Tokens

You have probably heard about the Digital Tokens in Ethereum. It is a special kind of the Smart Contract that allows users to exchange the funds/goods/cats other than Ethereum, but using Ethereum’s Blockchain. It is commonly used in ICO projects (Initial Coin Offerings).The ICO is something between the Kickstarter and a stock exchange. Already existing companies or newly opened startups are looking to gather funds for the development. In order to do that they offer investors Digital Tokens which are stored in the Blockchain. Once the tokens are withdrawn, they can be exchanged, bought or sold by the owners. The price is or may be related to the company value.

How to run Ethereum Geth Node

The node that I would recommend for connecting with Ethereum is called Geth. It is the command line interface with a full Ethereum node implemented in Go. Geth is an open source project and can be found in the GitHub repository at https://github.com/ethereum.

The Ethereum software is divided into three parts responsible for different parts of the work:

  • the Ethereum Virtual Machine, responsible for computations,
  • the Swarm, responsible for peer-to-peer file sharing,
  • Whisper, a messaging protocol that allows sending messages to other nodes.

Geth Installation

Because the Geth software is available on the windows, mac os, and linux platforms, I will stick to the Ubuntu environment. If you're using another, please see the instructions available at https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum.

Geth can be obtained in two ways — compiled from the source or installed from the PPA. PPA is easier and does not require one to install additional software or the Go language.

sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum

After executing this code on the command line, a new geth application should be available. You can check with the geth -h.

Start the Geth Node

Running the geth software is not as obvious as it may look like. When you execute geth on the command line, it will immediately start synchronizing with the Blockchain. In our case, we will need to enable a couple of features that are not included with the standard command:

geth --rpc --rpcapi="db,eth,net,web3,personal,web3"

This will run geth and enable the RPC API, including selected features that will allow our application to download the data we need. Like Bitcoin, Ethereum, too, has a TestNet or three. The Ropsten for testing Proof Of Work concept, Kovan — for Parity purposes and Rinkeby for geth. We will use the last one (https://rinkeby.etherscan.io/).

Running geth in TestNet mode requires only one additional flag: --rinkeby:

geth --rinkeby --rpc --rpcapi="db,eth,net,web3,personal,web3" --rpccorsdomain "http://localhost:3000"

Now, the API is broadcasted at the address http://127.0.0.1:8545. The rpccorsdomain flag will allow us to connect to the RPC API from this specific domain. I set this to the localhost:3000 because it is the default address for React’s boilerplate.

WARNING: In this case, the RPC API is enabled, and the communication between your application and the Ethereum’s node should be well secured. At the very least, it should not be available from the Internet otherwise it may get hacked.

Geth’s Console

Geth as a tool delivers a console that allows us to perform some actions on the Ethereum’s Blockchain, like managing accounts, addresses, reviewing blocks or transactions. The majority of the commands available in this console are the same methods that we will use in the API.

Geth’s console is included as an attach argument. To connect to it, we need two things — a running Ethereum node and a specified ipc file, which is an inter-process file. We will need to use the file from the rinkeby folder:

geth attach ipc:~/.ethereum/rinkeby/geth.ipc

Afterwards, we can check if everything works correctly. Try to run the command eth.getBlock() within the console. It should return the highest block in the chain.

HINT: If the highest block in the chain is 0, please double-check whether the node is synchronized with the Blockchain. You can do it by checking the log of the running node, or by typing eth.syncing in the console. This command displays all information about current state of the node.

Create an Account

Our next step is creating an Account. The Account is similar to the Wallet in Bitcoin and is mandatory to operate on the assets. Geth delivers a special argument that allows for account management. To create a new account you can execute:

geth --rinkeby account new

This command will ask you for the passphrase that protects your account and will return an Ethereum address that will be used for further work.

Now, we can check currently opened accounts on our node by calling:

geth --rinkeby account list

The presented list has two columns — the address and keystone file, which can be used as a backup file for the account If we lose the node or would like to use another piece of software to manage the account, e.g. a web interface. In that case, we can generate a private key to the account or use the keystone file.

It is also possible to check the list of accounts in the Attach console. The eth.accounts method will present all created addresses.



Transaction Lifecycle

As in the previous part, I would like to present a full transaction lifecycle. Let’s go back to our previous example with the e-commerce website where the user can buy goods and pay with the fiat currency and already implemented Bitcoin. Now, we would like to add a new case — the Ethereum payment method.

Even with the huge list of differences between them, Bitcoin and Ethereum are based on the same cryptocurrency principles — anonymity, transparency and information sharing. So, the transaction lifecycle will look exactly the same as in part #4 — the application will generate an address for the order, the user will send funds to this address, and we will watch the Blockchain for the latest blocks and list all transactions inside that will be sent to this address. After that, we will just decide how many confirmations we need to trust the transaction.

Step #0 — Connect to the Geth

Our first step is to connect to the Geth node from the JavaScript application. Fortunately, geth delivers an RPC API endpoint (a real-time connection) which can be handled by the web3.js library — https://github.com/ethereum/web3.js. To install the web3 library, we can use npm package manager:

npm install web3

Now we should be able to connect to the node and download basic information. Let’s start with the list of accounts:

var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log(web3.eth.accounts)

As you can see, the web3 packager delivers commands really similar to the ones available in the console.

I know that the code does not look pretty, and the configuration should be moved to the environment variables, etc., but in this tutorial, I would like to focus exclusively on the connection between a JavaScript application and the Ethereum node. If you would like to polish your React’s or JavaScript’s skills, I can recommend the resources shared at https://x-team.com/javascript-resources/.

Step #1 — Generate a New Address

Let’s move to the e-commerce shop page and imagine how the user orders items. She adds new products to the order, and when she is done and ready, she enters the delivery data and the method of payment. We would like to add a new method here — the Ethereum. After the user accepts this method, a new address should be generated and presented to the user — preferably as a QR code and a piece of text that she can copy-paste to her wallet. It should be displayed in both ways because some users use mobile applications to pay with Ethereum and others use web applications or even geth’s console.

At this point, Ethereum works a little bit different than Bitcoin, because it is not possible to add more than one address to the account as each account needs to be secured with a passphrase. Moreover, that is why Ether’s transactions only have one sender and one receiver. The funds are not kept in one wallet. However, the transaction fees are pretty low in comparison to Bitcoin and the confirmation time is short, so that is not a problem.

Thus, we will need to create a new account for each user and keep a randomly generated passphrase in the database. I would recommend automating the process of transferring funds, after they have been confirmed on each wallet, to some other address that will not have its passphrase saved in the database. I will explain how to do it in step #5.

To generate a new address from the JavaScript code, we can use the method available in the personal namespace, web3.personal.newAccount, which will accept one parameter with the passphrase. This passphrase should be encrypted and saved with the address for further purposes, otherwise, you will lose access to this account.

var newAccount = web3.personal.newAccount('testpassphrase')
console.log(newAccount)

A new address will be generated, which can be presented to the user.

Step #2 — Wait for Payment

Now, we are waiting for the user’s action. She needs to copy-paste or scan the address and transfer funds to our wallet.

Step #3 — Get the Transaction from the Latest Block

In this step, we will watch the last published blocks and compare the transaction receivers with our list of saved addresses. I chose this method because it is much quicker than the alternatives I took into consideration. We could watch all the addresses and check the current balance or a list of transactions assigned to specific addresses, but both methods will generate an enormous number of API calls because, after some time, I expect to have hundreds or thousands of newly generated addresses saved in the database I'll be checking against.

So, I prefer to get the last published block and compare the transactions’ receivers with the list of addresses generated by our application. We can use getBlock method, which accepts one parameter — the block hash. It does not have a default parameter set to the latest block, but we can use the word “latest” which will be properly resolved by the interpreter.

web3.eth.getBlock(“latest”)

This method will return all the information about the block, including the hash, number, size, timestamp, and list of transaction Ids. Unfortunately, that's only Ids for transactions. To get complete information about each transaction, we will need to call another method, getTransaction, which will return the transaction object.

To automate this process a little bit and get only receivers from transactions we can use the following code:

var block = web3.eth.getBlock('1644382')
block.transactions.forEach((transaction) => {
  console.log(web3.eth.getTransaction(transaction).to)
})

Now, if the receiver is found in our database, we save the first confirmation for the payment. In the example, I passed the block number into the getBlock method, because that is also acceptable besides "latest" or the hash. This is helpful because Ethereum’s Blockchain publishes blocks every 12 seconds, so if you would like to run a cronjob, which will be executed every minute, you will need to check at least the last five blocks. My solution for that case is to save the number of the last checked block and increase it when the next cronjob executes.

Step #4 — Gather Confirmations

Ethereum does not return a confirmation number as Bitcoin does. Each new block that is published on the ledger can be treated as a new confirmation for already mined transactions. In this case, we can use two different approaches. Let’s assume that we need five confirmations — the transaction will be secured in about 1 minute, and this is just enough to ensure that we are not in the uncle tree.

The first approach is watching the block like in the previous step. However, not the latest block or blocks, but rather the block which is five confirmations behind the latest block which we checked or the last published block.

var block = web3.eth.getBlock(web3.eth.blockNumber - 5)


block.transactions.forEach((transaction) => {
  console.log(web3.eth.getTransaction(transaction).to)
})

The second approach includes listing all pending transactions from our database and getting the block number from the getTransaction method.

var transactionIdFromDB = '0x2b22e4604bbaa4e3570c9d08121d224790561bfa50f203e1dcc43cc9c90da758';
var transaction = web3.eth.getTransaction(transactionIdFromDB)

if ((transaction.blockNumber - web3.eth.blockNumber) > 5) {
  //confirm transaction
}

Step #5 — Transfering Funds to an External Wallet

When the system notices that the funds have been transferred, I strongly recommend moving them to an external account which is not connected to the application. Just in case. Some applications require you to keep coins for pay-back, so 90% of funds can be transferred to a safe wallet and the rest to the pay-back wallet, which can be connected to the application.

The Web3 package delivers an easy-to-use method for transferring funds from one account to another — sendTransaction. Unfortunately, this method does not accept the passphrase which is required to send the transaction. Before we try to make a transfer, we need to unlock the account and go through authorization with the passphrase.

To do it, we need to use the unlockAccount method in the personal namespace:

web3.personal.unlockAccount('0x63e707fce38c59267838ff91090b5616aae7e26b', '1234', 3)

This method accepts three arguments — the account, the passphrase, and the number of seconds after which the account will be locked again. It returns a boolean value that tells if the operation succeeded or not.

After that, we are able to send the transfer using the method sendTransfer:

var transactionIdFromDB = '0xc810577c36e4f5cd106b7040759554b11b4c83bb8acb730fb989b294aae99f17';
var transaction = web3.eth.getTransaction(transactionIdFromDB)
var safeAccountAddress = '0x63e707fce38c51132317497192734917239419bb'

var transactionObject = {
  from: transaction.to,
  to: safeAccountAddress,
  value: transaction.value
}

web3.eth.estimateGas(transactionObject, function(error, gas) {
  web3.eth.getGasPrice(function (error, gasPrice) {
    var gasPrice = Number(gasPrice);
    var transactionFee = gasPrice * gas;

    transactionObject.value = -(transactionObject.value - transactionFee);
    web3.eth.sendTransaction(transactionObject);
  })
});

In the code, I create a new transaction object which defines a transfer from the account that received funds, to the safe account with the value of transfer minus the calculated fee that is required to send the transaction. The fee is calculated by the formula GasPrice * RequiredGas.

Conclusion

In this chapter, we have learned about Ethereum, which is both similar to and different from Bitcoin. We have also been able to successfully implement a full transaction lifecycle for our e-commerce shop. In the next part, I will show you how to use and write Smart Contracts.

04 Milestones

SCALE YOUR DEVELOPMENT TEAM

We help you execute projects by providing trusted Blockchain developers who can join your team and immediately start delivering high-quality code.

Hire Blockchain Developers