Create your own Blockchain using Python and Ethereum

October 24, 2018 0 21
Create your own Blockchain using Python and Ethereum

Blockchain, as the name suggests, is a collection of blocks or data records chained together in a cryptographic fashion. Each block in the chain contains a hash of the previous block, timestamp, and the transaction data, securing it from intruders/attackers and modifications in the future. This immutability is one of the most interesting features of the Blockchain. Transactions, once written, are very difficult to modify (it is possible to modify the chain from a particular block but that means splitting the chain in two and to do that 51% of the miners have to agree to use the new chain.)

The best thing about Blockchain that makes it secure is the way it is decentralized, meaning you cannot access it from any centralized location or modify certain blocks in a Blockchain to hack the transactions. Any attempt to modify the chain needs consensus from more than 50% of the miners for the chain. Very difficult to achieve.

In this blog, I will be talking about some basic Blockchain concepts and I will try to illustrate them with an example of creating a simple Blockchain using Ethereum and Python on a Linux/Ubuntu box.


  • Any Ubuntu VM (desktop/server) with minimum 2 GB RAM and 10 GB disk space
  • Python 3.5 or 3.5+
  • Ethereum basics
  • Basic understanding of Blockchain
sudo add-apt-repository ppa:jonathonf/python-3.6 
sudo apt-get update 
sudo apt-get install python3.6
sudo apt-get install ethereum
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum

So, let’s start with your very own Blockchain:

1. The first step in creating Blockchain is to create an initial block of the chain using the config file. This initial block will basically define the properties of your whole Blockchain.

2. Under your working directory create a JSON file that holds the configuration for the initial block.

sudo vi firstblock.json and paste the below content in it.

    "config": {
   	"chainId": 1,
   	"homesteadBlock": 0,
   	"eip155Block": 0,
   	"eip158Block": 0,
   	"byzantiumBlock": 0
    "difficulty": "100",
    "gasLimit": "4000000",
    "alloc": {
   	"8c684d22367d208c46584dcf7f09d8bc8f56ffff": {
           "balance": "500000000000000000000000"
     "ge14d41d66af28385c7af6d825ab102eb271ffff": {
       	"balance": "10000000000000000000000"

Let’s have a look at the information headings in the JSON file:

  • chainId : This is your chain’s identifier, and is used in replay protection.
  • homesteadBlock, eip155Block, eip158Block, byzantiumBlock : These relate to chain forking and versioning, so in this particular case lets just keep them aside as you are starting a new Blockchain.
  • Difficulty: This dictates how difficult it is to mine a block. Setting this to a low value (~10–10000) is helpful in a private Blockchain as it lets you mine blocks quickly, which equals fast transactions, and plenty of ETH to test with.
  • gasLimit: This is the total amount of gas that can be used in each block. With such a low mining difficulty, blocks will be moving pretty quick, but you should still set this value pretty high to avoid hitting the limit and slowing down your network.
  • Alloc: Here you can allocate ETH to specific addresses. This won’t create the account for you, so make sure its an account you already have control of. You will need to add the account to your private chain in order to use it and to do so you need access to the keystore/utc file

3. Initialize your data-directory for the first node creation.

geth --datadir ./node1 init ./firstblock.json

You should see output similar to this:

INFO [09-04|10:07:13.814] Maximum peer count                       ETH=25 LES=0 total=25
INFO [09-04|10:07:13.815] Allocated cache and file handles         database=/home/vinay/my-chain/node1/geth/chaindata cache=16 handles=16
INFO [09-04|10:07:13.821] Writing custom genesis block
INFO [09-04|10:07:13.821] Persisted trie from memory database      nodes=3 size=413.00B time=83.769µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [09-04|10:07:13.822] Successfully wrote genesis state         database=chaindata                                            hash=9d236a...641806
INFO [09-04|10:07:13.822] Allocated cache and file handles         database=/home/vinay/my-chain/node1/geth/lightchaindata cache=16 handles=16
INFO [09-04|10:07:13.827] Writing custom genesis block
INFO [09-04|10:07:13.827] Persisted trie from memory database      nodes=3 size=413.00B time=57.041µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [09-04|10:07:13.827] Successfully wrote genesis state         database=lightchaindata                                            hash=9d236a...641806

4. Now you can start your node with the below command:

geth --datadir ./node1 --networkid 111 console 2>> node1.log

This will ensure that all the logs are redirected to node1.log under your specified working directory for your node, which is node1 in our case.

After running the above command, you should see something like this in your output:

INFO [09-04|10:07:27.687] Maximum peer count                       ETH=25 LES=0 total=25
INFO [09-04|10:07:27.688] Starting peer-to-peer node               instance=Geth/v1.8.15-stable-89451f7c/linux-amd64/go1.10
INFO [09-04|10:07:27.688] Allocated cache and file handles         database=/home/vinay/my-chain/node1/geth/chaindata cache=768 handles=512
INFO [09-04|10:07:27.698] Initialised chain configuration          config="{ChainID: 1994 Homestead: 0 DAO:  DAOSupport: false EIP150:  EIP155: 0 EIP158: 0 Byzantium: 0 Constantinople:  Engine: unknown}"
INFO [09-04|10:07:27.698] Disk storage enabled for ethash caches   dir=/home/vinay/my-chain/node1/geth/ethash count=3
INFO [09-04|10:07:27.698] Disk storage enabled for ethash DAGs     dir=/root/.ethash                                     count=2
INFO [09-04|10:07:27.699] Initialising Ethereum protocol           versions="[63 62]" network=1114
INFO [09-04|10:07:27.700] Loaded most recent local header          number=0 hash=9d236a...641806 td=400
INFO [09-04|10:07:27.700] Loaded most recent local full block      number=0 hash=9d236a...641806 td=400
INFO [09-04|10:07:27.700] Loaded most recent local fast block      number=0 hash=9d236a...641806 td=400
INFO [09-04|10:07:27.700] Regenerated local transaction journal    transactions=0 accounts=0
INFO [09-04|10:07:27.700] Starting P2P networking
INFO [09-04|10:07:29.811] UDP listener up                          self=enode://75dc65374999c58d39ae9f8e8e40d3c750ff4561d67995827a907c91d0e1ed718239dd1e5817f99d3544ad32a81a002cdd925e21afb3f1c39823cb8fcdf28b7b@
INFO [09-04|10:07:29.811] RLPx listener up                         self=enode://75dc65374999c58d39ae9f8e8e40d3c750ff4561d67995827a907c91d0e1ed718239dd1e5817f99d3544ad32a81a002cdd925e21afb3f1c39823cb8fcdf28b7b@
INFO [09-04|10:07:29.815] IPC endpoint opened                      url=/home/vinay/my-chain/node1/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.8.15-stable-89451f7c/linux-amd64/go1.10
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

This is your javascript console where you can use different Blockchain commands to play around with your Blockchain.

5. Create your personal account:
If you have already created this as a part of JSON file created (alloc param), then you can simply import that into your keystore folder created during data directory instantiation, which in our case is “/node1/keystore” and jump to the next step.

You can create a new account using the following command:


Remember the passphrase you give to your account because if you forget it, there is no way to recover your account.

You can view the accounts created using the following command:

> web3.eth.accounts
["0x46574bcfce83947b684097fd21395fa22c4d8cb8", "0x1ef45cc951acfff4c2101c9b3ca7131a2fd7c809"]

To set your default account, use the following command:

> miner.setEtherbase(web3.eth.accounts[0])

This will set the first account in the list to be the default account.

You can check your balance for the given account with the following command:

> eth.getBalance(eth.coinbase)

6. Run mining command and you will see your account balance increasing:


You should also see the mining logs being dumped to the log that we instantiated as part of data directory initialization.


This will stop the mining action.

Now that your first node is ready, you can add peer nodes to the original node by following these steps:

1. Initialize a new data directory for the new node just like your first node using the same JSON that you created initially.

geth --datadir ./node2 init ./firstnode.json

2. Launch the peer node from some different port on a separate console:

geth --datadir ./node2 --networkid 111 --port 30304 console 2>> node2.log

Remember that you need to provide the same networkid that you used for the first node so that it becomes a peer node for the first node.

This will open a new javascript console and you can run all the Ethereum commands similar to your first node.

3. Type the following on the javascript console of the first node:


You should see an output similar to this:


4. Now run the following command on your second node’s console:

> admin.addPeer("enode://483ae85d264b8ebdc6c01565694cd8e24d17cd9ad9ba9c05ab83e8a9d477ad9b397eb2afd84d65e581ef2007f1e0338268f526cbd4b93481713c1ae2080533c5@")

5. Verify that your nodes are communicating.
Type the following command on the console of the second node:

> admin.peers
The output should be something similar to this:
    caps: ["eth/63"],
    id: "483ae85d264b8ebdc6c01565694cd8e24d17cd9ad9ba9c05ab83e8a9d477ad9b397eb2afd84d65e581ef2007f1e0338268f526cbd4b93481713c1ae2080533c5",
    name: "Geth/v1.8.15-stable-89451f7c/linux-amd64/go1.10",
    network: {
      inbound: false,
      localAddress: "",
      remoteAddress: "",
      static: true,
      trusted: false
    protocols: {
      eth: {
        difficulty: 72443634457,
        head: "0x49a60106a525099d51f1a093d21676a2081c8e4b3d0322c5cc40d95563ba13bd",
        version: 63

remoteAddress: “” -> indication that the node is listening to the first node that is created over 30303.

Congratulations! Your Blockchain is ready!

Leave Comment

Your email address will not be published.

Stay up to date with the latest and the best from the world of automation!