My first steps with Ethereum

As a Fullstack Blockchain Developer, I wanted to get my hands dirty on a new blockchain technology. I picked Ethereum because I’ve experimented before with the technology… without success. At that time, Ethereum was still in its infancy. Today, I see Ethereum as a toddler, worth a second attempt. I’ll go through some important steps I’ve taken and things I’ve noticed. Disclaimer: This is not a full tutorial. An all-encompassing tutorial can be found here.

Install Ethereum

I’ve created a separate Virtual Machine with Ubuntu 16.04 for this experiment. This experiment will make use of a local private Ethereum test network for easy development. Ethereum can be installed on your machine with the following commands:

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

This allows us to use geth with the command line interface. Geth is a Go client for use with Mist, suitable for Dapp development. This will be useful later in this article.

Defining the Genesis block

A Genesis block is the first block in the chain, block 0, and the only block that does not point to a predecessor block. When first looking into Genesis block definitions, I was a bit confused. There are many variations (1, 2, 3) out there on the Internet. A custom Genesis block allows you to change specific configuration settings for your private Ethereum blockchain like gas limit and mining difficulty.

The first Genesis block definition I found, is the one defined by the official Go-Ethereum documentation.

{
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"difficulty": "200000000",
"gasLimit": "2100000",
"alloc": {
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": {
"balance": "300000"
},
"f41c74c9ae680c1aa78f42e5647a62f353b7bdde": {
"balance": "400000"
}
}
}

I tried to initialize the Genesis block with this configuration, however, geth rejected the config file. Why? We are allocating funds to non-existing addresses (wallets). If you want to allocate funds to certain addresses to avoid the need for mining, you have to create those with geth. A new account can be easily created with geth account new. The command will return a new address which you can add to your custom Genesis file under the "alloc" field.

The example by Go-Ethereum is the most basic version of a custom Genesis file (required fields: config, difficulty, gasLimit and alloc). I’ll try to give a proper explanation for the relevant options and the values used (1):

  1. “config”: Contains the blockchain configuration.
    - “chainId”: ChainId identifies the current chain and is used for replay attack protection.
    - “homesteadBlock”: Indicates that you are using the Homestead version release of Ethereum.
  2. “difficulty”: Sets the mining difficulty applied during the discovery of the first block. The value used is a scalar value. It is recommended to use a low value so you can easily gain Ether to fund your accounts and avoid long waiting times during test execution since mining a valid block is required to execute a transaction on the blockchain. The lowest value you can set is 0x4000 which allows you to mine blocks within 100’s of milliseconds.
  3. “gasLimit”: A chain-wide limit of Gas expenditure per block. I’ve set this value very high to avoid being limited during testing. Keep in mind to check the Gas consumption of your smart contracts. A very high consumption should be avoided and mostly indicates that there’s something wrong with your smart contract.
  4. “alloc”: This field gives the possibility to define pre-filled addresses. This field accepts a value expressed in Wei. One Ether results in 10000000000000000000 Wei.

Playing around with Geth

Blockchain deamon
Deamon to keep private blockchain running in background with the use of the geth command. Contents of Bash script (2):

#!/bin/sh
PORT=30303
RPCPORT=8000
NETWORKID=42
IDENTITY="MyPrivateChain"
DATADIR=/home/$USER/eth/priv/data
NAT=none
RPCADDR="0.0.0.0"
IPCPATH=/home/$USER/eth/priv/data/geth.ipc
nohup geth --rpc --ws --port $PORT --rpcport $RPCPORT --networkid $NETWORKID --datadir $DATADIR --nat $NAT --identity $IDENTITY --rpcaddr $RPCADDR --wsaddr $RPCADDR --rpcapi "db,eth,net,web3,personal,parity,miner" --maxpeers 2 --rpccorsdomain * --ipcpath $IPCPATH &

To use this script, give it executable rights ( chmod +x script.sh ) and exute it ( ./script.sh ). Note the --rpcapi option, here we can define which APIs we want to have at our disposal over the HTTP-RPC interface (default: “eth, net, web3”). It is a good idea to include personal, parity, miner as well.

Useful Geth commands
First, let’s attach the geth console to the rpcport with 
> get attach http://0.0.0.0:8000. This allows us to use the APIs for creating an account and starting a miner.

  • Create new account: 
    > personal.newAccount("password")
  • Unlock account:
    > personal.unlockAccount(eth.accounts[0], "password", 0) 
    You’ve to unlock your account each time you start a new geth console. As the first parameter, you give the account you want to unlock. You can also use personal.listAccounts[0]. The last parameter indicates that we want to unlock the account for an indefinite period until the geth console is closed.
  • Check balance for specific account (Ether):
    > web3.fromWei(web3.eth.getBalance(web3.eth.accounts[0]))
  • Set Etherbase account to allocate mined funds:
    > miner.setEtherbase(personal.listAccounts[0])
  • Start 4 miner threads (it’s normal that the function returns a null value):
    > miner.start(4)
  • Check hashrate (~check if miner is operational):
    > miner.getHashrate()
  • Stop miner:
    > miner.stop()

Web3 API Reference

It is possible to use the Web3 API object in your code. This allows you to interact with your private blockchain. Here are some code snippets to indicate the use with JavaScript.

Let’s start with the connection to the rpcpath, and immediately unlock your main account.

export function initWebService() {  
  web3.setProvider(
new web3.providers.HttpProvider(
'http://localhost:8000',
0,
"0x8d2e50cd0e654399229cF88cb05E0F3074928FCe",
"password"
)
)
}

Next, I want to display all the accounts and balances (logged in console). As you can see, the commands are exactly the same as in the geth console.

export function getAccounts() {   
return web3.eth.getAccounts( (err, accs) => {

if (err != null) {
return 'There was an error fetching your accounts.'
}else if (accs.length == 0) {
return 'Couldn\'t get any accounts!'
} else {
accs.forEach( acc => {
web3.eth.getBalance(acc).then( balance => {
console.log(balance)
})
})
}

})
}

Full project can be found here: https://github.com/michielmulders/web3-ethereum-api-test/tree/master

Sources

(1) https://ethereum.stackexchange.com/questions/2376/what-does-each-genesis-json-parameter-mean Credits for explaining the Genesis parameters.

(2) https://steemit.com/ethereum/@nphacker/setting-up-and-running-a-private-ethereum-blockchain-on-ubuntu Credits for using the deamon script which I have slightly changed.

(3) https://souptacular.gitbooks.io/ethereum-tutorials-and-tips-by-hudson/content/private-chain.html Another definition with different values for Genesis config file.

(4) Kevin Leyssens: Many thanks for the documentation and code you provided.