Contact Us

Contact Us



Pleas confirm by checkbox


Uncategorized

Hacking ethereum to inject our own consensus algorithum Part-1

Author_img
By Hemant Sachdeva July 23, 2018

Recently, I have been going through the source of Ethereum to see if I can change it’s proof of work consensus algorithm with our own algorithm. By doing that I developed an insight of Ethereum source code which I would like to share. The goal of this blog post is to first setup Ethereum development environment and then build very simple consensus algorithm. The consensus algorithm will be very simple as main goal of this activity is to understand the internals of Ethereum. To follow along reader is expected to be equipped with following skills:

  • Understanding of ‘go’ language : As Ethereum (geth implementation) is written in go language it is expected that you should have good grasp of language. If you are not familiar with go language it is good motivation to learn now.
  • Understanding of how blockchain works : Understanding how blockchain works in general is required. There are quite amazing blogs which explain the working of blockchain.
  • Understanding of Ethereum : You cannot hack the application if you don’t know how it works at high level. So understanding of Ethereum at high level is required.

Good development set up makes life easier for making changes to the source code. I have been using ‘goLang’ from jetBrains for a year now. It is very good IDE for go development and have very good debug support. I also use Atom IDE for small projects but for dealing big projects goLang is amazing. Following are the step you need to perform to setup development environment:

  • Make sure go is setup properly. To check if it installed on your machine or not type following command in terminal:

> go version

go version go1.9.2 darwin/amd64

If command responds with proper version, you have go installed. If it is not, install command will throw an error “ -bash: go: command not found”.

To install ‘go’, follow instruction specific to your OS platform listed here : https://golang.org/doc/install

  • Make sure GOPATH environment variable is properly set up
 > echo $GOPATH
 /Users/hemants/Projects/mist/go-workspace

/Users/hemants/Projects/mist/go-workspace

  • Clone Ethereum GitHub repository
> cd $GOPATH/src/github.com/ 
> mkdir ethereum
> git clone git@github.com:ethereum/go-ethereum.git
  • Import Ethereum code into GoLand IDE by clicking on ‘open project’ button and locating the directory where you have checked out Ethereum code.
  • Once imported successfully run to file go-ethereum/cmd/geth/main.go, right click and run. This will report following errors:
cmd/geth/main.go:125:3: undefined: configFileFlag
cmd/geth/main.go:156:3: undefined: initCommand
cmd/geth/main.go:157:3: undefined: importCommand
cmd/geth/main.go:158:3: undefined: exportCommand
cmd/geth/main.go:159:3: undefined: importPreimagesCommand
cmd/geth/main.go:160:3: undefined: exportPreimagesCommand
cmd/geth/main.go:161:3: undefined: copydbCommand
cmd/geth/main.go:162:3: undefined: removedbCommand
cmd/geth/main.go:163:3: undefined: dumpCommand
cmd/geth/main.go:165:3: undefined: monitorCommand
cmd/geth/main.go:165:3: too many errors
  • To resolve above mentioned problem go to Run > Edit Configurations > Go Applications > select the run configuration you want to edit > Run kind and change it to File from Package. Then type the name of the package, github.com/ethereum/go-ethereum/cmd/geth and save the settings.

Our development environment is ready. Congrats !! :).

Set up local private Ethereum blockchain

To set up private Ethereum blockchain running locally, let’s first install ‘geth’ tool into $GOPATH/bin directory. To do that, open terminal and go to location $GOPATH/src/github.com/ethereum/go-ethereum, then execute following command from terminal

> go install -v ./cmd/geth

Go to location $GOPATH/bin/ to test if geth is installed properly or not. Issue following command, you should see following result.

> ./geth version
Geth

Version: 1.8.12-unstable

Architecture: amd64

Protocol Versions: [63 62]

Network Id: 1

Go Version: go1.9.2

Operating System: darwin

GOPATH=/Users/hemants/Projects/mist/go-workspace

GOROOT=/usr/local/Cellar/go/1.9.2/libexec

Next, create file name ‘privategensis.json’ with following content :

{

"config": {

"chainId": 15,

"homesteadBlock": 0,

"eip155Block": 0,

"eip158Block": 0

},

"difficulty": "2000000",

"gasLimit": "21000000",

"alloc": {

}

}

Go $GOPATH/bin and initialise local Ethereum blockchain by issue following command:

> ./geth --datadir ~/.ethereum/myprivatenet init privategensis.json
INFO [06-21|13:43:05.226227] Maximum peer count ETH=25 LES=0 total=25

INFO [06-21|13:43:05.240084] Allocated cache and file handles database=/Users/hemants/.ethereum/myprivatenet/geth/chaindata cache=16 handles=16

INFO [06-21|13:43:05.244943] Writing custom genesis block

INFO [06-21|13:43:05.245018] Persisted trie from memory database nodes=0 size=0.00B time=10.217µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B

INFO [06-21|13:43:05.24539] Successfully wrote genesis state database=chaindata hash=07185f…82bcc4

INFO [06-21|13:43:05.245414] Allocated cache and file handles database=/Users/hemants/.ethereum/myprivatenet/geth/lightchaindata cache=16 handles=16

INFO [06-21|13:43:05.24758] Writing custom genesis block

INFO [06-21|13:43:05.247618] Persisted trie from memory database nodes=0 size=0.00B time=2.699µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B

INFO [06-21|13:43:05.247787] Successfully wrote genesis state database=lightchaindata hash=07185f…82bcc4

This will generate the genesis block for our private blockchain at location : “/.ethereum/myprivatenet”. Lets run our blockchain by issuing following command :

./geth -rpc -rpcapi 'web3,eth,debug,personal' -rpcport 8545 --rpccorsdomain '*' --datadir ~/.ethereum/myprivatenet --networkid 15
INFO [06-21|13:49:27.007881] Maximum peer count ETH=25 LES=0 total=25

INFO [06-21|13:49:27.01546] Starting peer-to-peer node instance=Geth/v1.8.12-unstable/darwin-amd64/go1.9.2

INFO [06-21|13:49:27.015503] Allocated cache and file handles database=/Users/hemants/.ethereum/myprivatenet/geth/chaindata cache=768 handles=128

INFO [06-21|13:49:27.028411] Initialised chain configuration config="{ChainID: 15 Homestead: 0 DAO:  DAOSupport: false EIP150:  EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Engine: unknown}"

INFO [06-21|13:49:27.028465] Disk storage enabled for ethash caches dir=/Users/hemants/.ethereum/myprivatenet/geth/ethash count=3

INFO [06-21|13:49:27.028479] Disk storage enabled for ethash DAGs dir=/Users/hemants/.ethash count=2

INFO [06-21|13:49:27.028513] Initialising Ethereum protocol versions="[63 62]" network=16

INFO [06-21|13:49:27.029799] Loaded most recent local header number=0 hash=07185f…82bcc4 td=2000000

INFO [06-21|13:49:27.029836] Loaded most recent local full block number=0 hash=07185f…82bcc4 td=2000000

INFO [06-21|13:49:27.029845] Loaded most recent local fast block number=0 hash=07185f…82bcc4 td=2000000

INFO [06-21|13:49:27.03009] Loaded local transaction journal transactions=0 dropped=0

INFO [06-21|13:49:27.030331] Regenerated local transaction journal transactions=0 accounts=0

INFO [06-21|13:49:27.030806] Starting P2P networking

INFO [06-21|13:49:29.146101] UDP listener up self=enode://1dd1494242ee403a69fbb58a57505056f5fea5c9f4b207050ca0a1aecc36d74b4687ec1779320c6282d044aae0078437e5aa7688c29f04e1281cc3f5a0f954e2@[::]:30303

INFO [06-21|13:49:29.146426] RLPx listener up self=enode://1dd1494242ee403a69fbb58a57505056f5fea5c9f4b207050ca0a1aecc36d74b4687ec1779320c6282d044aae0078437e5aa7688c29f04e1281cc3f5a0f954e2@[::]:30303

INFO [06-21|13:49:29.150067] IPC endpoint opened url=/Users/hemants/.ethereum/myprivatenet/geth.ipc

INFO [06-21|13:49:29.150472] HTTP endpoint opened url=http://127.0.0.1:8545cors=* vhosts=localhost

 

In logs, look for line which says “IPC endpoint opened: url=/Users/hemants/.ethereum/myprivatenet/geth.ipc”.

This url allow us to interact with blockchain via IPC channel. Copy the path and fire new terminal and go to $GOPATH/bin and execute following command to attach to IPC channel :

./geth attach /Users/hemants/.ethereum/myprivatenet/geth.ipc

Welcome to the Geth JavaScript console!

modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

>

With this console we can execute various commands to interact with blockchain. If you look carefully, after connecting to IPC channel, console prints out all available modules with which you can interact. Namely modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 are the modules. To see what functionality is available to use from the console just enter the module name, It will print out all the function names which we can call from the console. Like type ‘personal’ in the console it will response with following function names and properties:

> personal

{

listAccounts: [],

listWallets: [],

deriveAccount: function(),

ecRecover: function(),

getListAccounts: function(callback),

getListWallets: function(callback),

importRawKey: function(),

lockAccount: function(),

newAccount: function github.com/ethereum/go-ethereum/console.(*bridge).NewAccount-fm(),

openWallet: function github.com/ethereum/go-ethereum/console.(*bridge).OpenWallet-fm(),

sendTransaction: function(),

sign: function github.com/ethereum/go-ethereum/console.(*bridge).Sign-fm(),

signTransaction: function(),

unlockAccount: function github.com/ethereum/go-ethereum/console.(*bridge).UnlockAccount-fm()

}

Let’s call listAccounts property to see if we have any account.

> personal.listAccounts

[ ]

As expected we don’t have any account yet. So let’s create one.

personal.newAccount(“password”)

“0x66c4c909098df782ef0a52464749de9ef294762c”

Now call personal.listAccounts

personal.listAccounts

[“0x66c4c909098df782ef0a52464749de9ef294762c”]

Let’s check the balance in this account, It should be zero.

> eth.getBalance(personal.listAccounts[0]).toNumber()

0

To generated some ether we need to mine some blocks. Before mining the block we need to tell our node to run as miner node. To do that issue following command

> miner.start(1)

After some time new blocks get generated. As you are the only miner in this network you will be rewarded with ether. Lets check the balance again

> eth.getBalance(personal.listAccounts[0]).toNumber()

10000000000000000000

Great we now have ethers. We can stop miner by specifying ‘miner.stop()’, to stop unnecessary mining. We can check the height of blockchain by running following command :

> web3.eth.getBlockNumber(function(e,r){ console.log(r)})

2

Which is telling us that current height of blockchain is 2. We can view any block by specifying it number by issuing following command :

> web3.eth.getBlock(1)

{

difficulty: 1903376,

extraData: "0xd88301080c846765746887676f312e392e328664617277696e",

gasLimit: 20979494,

gasUsed: 0,

hash: "0x6d719d3447497302f59aac284cbb7df585c4cc591c4d351d994d4c234c667ac7",

logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",

miner: "0x66c4c909098df782ef0a52464749de9ef294762c",

mixHash: "0x094731b8b22a8efba3327b61fe602d4e76e8857ff12db14c8d53afbd651260ff",

nonce: "0x082d1975e5cbe2c8",

number: 1,

parentHash: "0x07185fe5cd8ac52781a3893b7d08b1240c1ded9f84eb97ee68fe2901ed82bcc4",

receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",

sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",

size: 537,

stateRoot: "0xa3c4d51416278ab6c77c407027870d9a2c5e214d40e7d32f0275d692ca5ca69f",

timestamp: 1529571309,

totalDifficulty: 3903376,

transactions: [],

transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",

uncles: []

}

Amazing, now we have properly running Ethereum private network with development environment set up. We are ready to move on to next tutorial.

Related posts
VPC Sharing Using AWS RAM (Resource Access Manager)
Uncategorized

VPC Sharing Using AWS RAM (Resource Access Manager)

By shekhar.wagh June 18, 2019
Reduce App size with On Demand Resources
Uncategorized

Reduce App size with On Demand Resources

By shekhar.wagh May 29, 2019
iMessage Stickers and Apps
Uncategorized

iMessage Stickers and Apps

By shekhar.wagh May 27, 2019
What is UX Writing?
Uncategorized

What is UX Writing?

By shekhar.wagh April 08, 2019
AWS ECS (Amazon Elastic Container Service )
Uncategorized

AWS ECS (Amazon Elastic Container Service )

By shekhar.wagh March 26, 2019
Scala code analysis and coverage report on Sonarqube using SBT
Uncategorized

Scala code analysis and coverage report on Sonarqube using SBT

By shekhar.wagh March 19, 2019
Introduction to Akka Streams
Uncategorized

Introduction to Akka Streams

By shekhar.wagh March 08, 2019
Decentralized Applications - Utilizing the Power of Blockchain Technology
Uncategorized

Decentralized Applications - Utilizing the Power of Blockchain Technology

By shekhar.wagh March 05, 2019
App Store Connect API To Automate TestFlight Workflow
Uncategorized

App Store Connect API To Automate TestFlight Workflow

By shekhar.wagh February 28, 2019
Using Custom Metrics for CloudWatch Monitoring
Uncategorized

Using Custom Metrics for CloudWatch Monitoring

By shekhar.wagh February 06, 2019

Stay updated

Get the latest creative news from Fubiz about art, design and pop-culture.