We will be using 3 virtual machines as 3 Ethereum node. We used 'Ubuntu Server 14.04 LTS trusty', and 'Ubuntu 15.10 wily' for this experiment. Root Ethereum node will be referred as 'root node', client nodes will be referred as 'client node A' & 'client node B' respectively. On root node port 30303 must be accessible from outside.
Below are the installation instructions for the latest versions of Ubuntu. This step must be executed and Ethereum go client 'geth' must be installed on every node.
Before you can build the source, you need several tools and dependencies for the application to get started. First, update your repositories. Not all packages are provided in the main Ubuntu repository, those you'll get from the Ethereum PPA and the LLVM archive.
NOTE: 14.04 users, you'll need the latest version of cmake. For this, use:
sudo apt-add-repository ppa:george-edison55/cmake-3.x
Now add all the rest:
sudo apt-get -y update
sudo apt-get -y install language-pack-en-base
sudo dpkg-reconfigure locales
sudo apt-get -y install software-properties-common
wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
Depending on your Ubuntu version add the right llvm-toolchain source:
14.04:
sudo add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main"
15.04:
sudo add-apt-repository "deb http://llvm.org/apt/vivid/ llvm-toolchain-vivid-3.7 main"
15.10:
sudo add-apt-repository "deb http://llvm.org/apt/wily/ llvm-toolchain-wily-3.7 main"
Then continue:
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
sudo apt-get -y update
sudo apt-get -y upgrade
Use the following command to install geth:
sudo apt-get install ethereum
Following the bellow steps we will create our private Ethereum testnet.
Create a genesis.json file:
vi genesis.json
Insert following lines:
{
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x0100",
"coinbase": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "Custom Genesis Block",
"gasLimit": "0xffffffff"
}
A genesis block is the first block of a block chain. Modern versions of Bitcoin assign it block number 0, though older versions gave it number 1. The genesis block is almost always hardcoded into the software. It is a special case in that it does not reference a previous block, and for Bitcoin and almost all of its derivatives, it produces an unspendable subsidy.
For detailed explanation of genesis file component see here. Initialize network and start geth console:
geth --genesis genesis.json --datadir="~/test/" --port="30303" --networkid="93422" --rpc --rpcport="8545" --rpcaddr="172.31.11.117" --minerthreads="1" --mine --nodiscover --maxpeers=2 --nat="extip:54.239.25.200" console
NOTE: We will be using 54.239.25.200 as public ip address for our root node throughout this example.
In console we will now create an Ether base address:
personal.newAccount()
Now you will be prompted for enter new password. Choose your password.
Start mining and generate DAG:
miner.start(1)
NOTE: miner.start(1) means miner will start 1 mining instance and use 1 cpu for mining.
Example console output:
> miner.start(1)
I0114 19:08:35.952299 2153 mergedapi.go:63] miner_start [1]
I0114 19:08:35.952764 2153 types.go:106] Generated response: *shared.SuccessResponse &{%!s(float64=10) 2.0 %!s(bool=true)}
true
> I0114 19:08:35.954694 2153 miner.go:119] Starting mining operation (CPU=1 TOT=5)
I0114 19:08:35.955166 2153 statedb.go:270] (+) 2a82adcef610c15902085c83537a751389f8b728
I0114 19:08:35.955362 2153 state_object.go:161] 2a82adcef610c15902085c83537a751389f8b728: #0 5000000000000000000 (+ 5000000000000000000)
I0114 19:08:35.955728 2153 worker.go:571] commit new work on block 1 with 0 txs & 0 uncles. Took 765.622µs
I0114 19:08:35.956426 2153 ethash.go:220] Generating DAG for epoch 0 (size 1073739904) (0000000000000000000000000000000000000000000000000000000000000000)
I0114 19:08:35.956847 2153 agent.go:118] (re)started agent[0]. mining...
I0114 19:08:37.203563 2153 ethash.go:252] Generating DAG: 0%
I0114 19:08:42.264791 2153 ethash.go:252] Generating DAG: 1%
I0114 19:08:47.277945 2153 ethash.go:252] Generating DAG: 2%
I0114 19:08:52.221655 2153 ethash.go:252] Generating DAG: 3%
I0114 19:08:57.214285 2153 ethash.go:252] Generating DAG: 4%
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
I0114 19:16:57.645106 2153 ethash.go:252] Generating DAG: 97%
I0114 19:17:02.564308 2153 ethash.go:252] Generating DAG: 98%
I0114 19:17:07.534163 2153 ethash.go:252] Generating DAG: 99%
I0114 19:17:12.515090 2153 ethash.go:252] Generating DAG: 100%
I0114 19:17:12.517623 2153 ethash.go:237] Done generating DAG for epoch 0, it took 8m36.561200381s
Get nodeinfo:
admin.nodeInfo
Example console output:
{
enode: "enode://a0475b75e9d28d18a1b70cb61bb1bd6dcb1f786fc04e4fb194b9ae544fe8325f90d43b19cd1f4ab511801881ccde38df5b530757b3b9458da9c3107f0a6ec54d@[::]:30303?discport=0",
id: "a0475b75e9d28d18a1b70cb61bb1bd6dcb1f786fc04e4fb194b9ae544fe8325f90d43b19cd1f4ab511801881ccde38df5b530757b3b9458da9c3107f0a6ec54d",
ip: "::",
listenAddr: "[::]:30303",
name: "Geth/v1.4.0-unstable/linux/go1.5.1",
ports: {
discovery: 0,
listener: 30303
},
protocols: {
eth: {
difficulty: 1573120,
genesis: "696beda69b95581de321f9cf44d1123bdb2dcf8cc89d0ddce917071c221d07ed",
head: "76ec34b2129b1f4fd29357635b36e4b0a51c088c700ee82000c02de4b88da69d",
network: 93422
}
}
}
Check if root node is accessible from external network. We will execute following commands on some machine outside from the 'root node's' network.:
telnet 54.239.25.200 30303
sudo nmap -sU -p 30303 54.239.25.200
Work on root node is complete now. We will create two client node and connect to our root node.
Now we will prepare our client nodes. Execute following commands on both client nodes.
Start geth:
geth --genesis genesis.json --datadir="~/tests" --port="30303" --networkid="93422" --nodiscover --maxpeers=5 console
Create base address:
personal.newAccount()
We will be prompted for enter new password. Choose your password.
Now we will add our admin node:
admin.addPeer("enode://a0475b75e9d28d18a1b70cb61bb1bd6dcb1f786fc04e4fb194b9ae544fe8325f90d43b19cd1f4ab511801881ccde38df5b530757b3b9458da9c3107f0a6ec54d@54.239.25.200:30303")
Start mining and get some ether:
miner.start(1)
We have defined very low mining difficulty "difficulty": "0x0100", this will allow us to generate some Ether very quickly. After some time we will be able to see some balance on our client node.
Check balance:
web3.fromWei(eth.getBalance(eth.coinbase), "ether")
If everything works well we will be able to see some balance:
web3.fromWei(eth.getBalance(eth.coinbase), "ether")
57
Finally we are ready to transfer some balance. Let us assume base address of client node A is '0x036a03fc47084741f83938296a1c8ef67f6e34fa' and base address of client node B is '0xa8ade7feab1ece71446bed25fa0cf6745c19c3d5'.
Get base address of client node A:
personal.listAccounts
["0x036a03fc47084741f83938296a1c8ef67f6e34fa"]
Unlock account:
personal.unlockAccount("0x036a03fc47084741f83938296a1c8ef67f6e34fa")
Get base address of client node B:
personal.listAccounts
["0xa8ade7feab1ece71446bed25fa0cf6745c19c3d5"]
Finally let us make a transaction from client node A to client node B. We will execute following command on client node A.
eth.sendTransaction({from: '0x036a03fc47084741f83938296a1c8ef67f6e34fa', to: '0xa8ade7feab1ece71446bed25fa0cf6745c19c3d5', value: web3.toWei(1.7, "ether")})
Now let us check our pending transaction:
eth.getBlock("pending", true).transactions
Now after next block gets mined you will be able to see transferred balance on client node B. Check balance on client node B:
web3.fromWei(eth.getBalance(eth.coinbase), "ether")
Example console output:
1.7
Hi thanks for sharing,
but
geth --genesis genesis.json # failed with