Set up private blockchain on Amazon Web Service via geth and truffle suite
Content
Part I: Create a 2-node Ethereum network with private blockchain, and accounts on the two nodes can send ether to each other.
Part II: Deploy a contract from one node, and both accounts can access and execute functions on this contract
Part I (establishment of a private blockchain on AWS using geth)
Use t2.medium (2 vCPU, 4 GB RAM) with default 8G SSD.
Pick Ubuntu OS.
Make sure that the two nodes are with the same security group, which allows TCP 30303 (or 30000–30999 as I may use more ports on this range). Port 30303 by default is for peering among nodes.
For each of the nodes, do the following:
After ssh connection being made, first install prerequisites.
$ apt-get install software-properties-common curl git vim build-essential* install geth directlyadd-apt-repository -y ppa:ethereum/ethereum
apt-get update
apt-get install ethereum* Optional for geth source code modification and compilation$ git clone https://github.com/ethereum/go-ethereum.git
$ wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
$ tar -xvf go1.11.linux-amd64.tar.gz
$ mv go /usr/localexport GOROOT=/usr/local/go
export GOPATH=$HOME/go-ethereum
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
Or in the ~/.profile put the following in the end and source it.
Next install nodejs & truffle:
$ curl -sL https://deb.nodesource.com/setup_10.x | bash -
$ apt-get install -y nodejs
$ npm install -g truffle# Optional step (reduce the block interval for fast block creation if synchronization is not a big problem)
-> More details
- Edit the source code
$ cd go-ethereum/consensus/ethash/ && vim consensus.goMove to line 298.
Modify the CalcDiffculty function below.

The mining difficulty will remain at its lowest possible difficulty level on an ongoing basis.

2. Compile the source code
Add geth to the PATH, if bootnode is needed, do the following similarly.
$ make all && cp ./build/bin/geth /usr/local/binWrite down an Init config file (genesis file):
Ensure the same genesis file is applied to both nodes.
Do not set chainId to 0 and set a reasonable gas limit for your application.
My template: Genesis.json
{
“config”: {
“chainId”: 8888,
“homesteadBlock”: 0,
“eip155Block”: 0,
“eip158Block”: 0
},
“coinbase” : “0x0000000000000000000000000000000000000000”,
“difficulty” : “0x1000”,
“extraData” : “”,
“gasLimit” : “0x7a1200”,
“nonce” : “0x0000000000000042”,
“mixhash” : “0x0000000000000000000000000000000000000000000000000000000000000000”,
“parentHash” : “0x0000000000000000000000000000000000000000000000000000000000000000”,
“timestamp” : “0x00”,
“alloc”: {
}
}Initialization
$ geth init Genesis.jsonIf error occurs, probably chain data exists
In that case, use the following command
$ geth removedbStart geth
Personally, I use a tmux background session to watch the log output of geth in the background sessionand attach to the geth process when necessary in the main session.
In the tmux background session:
$ geth --nodiscoverIn the main session:
$ geth attachIn the tmux background session:
> personal.newAccount()
> eth.getBalance(eth.coinbase)
> miner.mine()
wait...
* optional
> miner.stop()
> admin.nodeInfo.enode
> admin.addPeer(<enode>)
* Check connection
> admin.peers
- Only one node requires to execute admin.addPeer and the connection will be made.
- AWS EC2 instance comes with a private IP address and a public IP address. Both works fine in add peering, but using private IP address is more convenient as it is not changed after instance STOP/START.
One one node:
> web3.fromWei(eth.getBalance(eth.coinbase), “ether”)
> personal.unlockAccount(eth.coinbase)
> eth.sendTransaction({from: eth.coinbase, to: "0xc8450add86799a376991cce3c66dc8fbaf77bd9d", value: web3.toWei(10, “ether”)})
> miner.start()If the coinbase of the other node gets the transaction, a private chain is established.
Part II (contract deployment with the help of truffle)
To put it first, web3deploy is a standard way of directly deploying a contract using nodejs, and truffle is a mature nodejs package accelerating the process.
Start RPC for truffle migration.
> admin.startRPC()
> personal.unlockAccount(eth.coinbase)Make sure at least one node is mining.
> miner.start()Truffle configuration
First make sure your solidity contract is in the right place of the truffle project for later compilation.
$ truffle compileEdit the truffle.js
module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*", // Match any network id } }};
In the migration folder, edit 2_deploy_contracts.js to deploy your own contact.

My dapp require large amount of synchronization time, so set to 0 meaning no timeout.
Now deploy the contract to the existing network (“development” specified in truffle.js).
$ truffle migrate --network development
Call contract fuction using command line
> personal.unlockAccount(eth.coinbase)
$ truffle exec <jsfile>
or
$ truffle consoleMy deployed contract function call example

Notice that if a typical error message may occur, i.e., “Transaction <addr> wasn’t processed in 240 seconds!”, it means you need to add the following line in the Javascript file to be executed by Javascript since the default transaction synchronization timeout is 240 seconds.
var MyContract = artifacts.require("./MyContract.sol");MyContract.synchronization_timeout = 0;