Skip to content

Creating a Private Network

A private network provides a configurable network for testing. By configuring a low difficulty and enabling mining, blocks are created quickly.

You can test multi-block and multi-user scenarios on a private network before moving to one of the public testnets.


An Ethereum private network created as described here is isolated but not protected or secure. We recommend running the private network behind a properly configured firewall.



Curl (or similar web service client)


To create a private network:

  1. Create Folders
  2. Create Genesis File
  3. Get Public Key of First Node
  4. Start First Node as Bootnode
  5. Start Additional Nodes
  6. Confirm Private Network Working

1. Create Folders

Each node requires a data directory for the blockchain data. When the node is started, the node key is saved in this directory.

Create directories for your private network, each of the three nodes, and a data directory for each node:

├── Node-1
│   ├── Node-1-data-path
├── Node-2
│   ├── Node-2-data-path
└── Node-3
    ├── Node-3-data-path

2. Create Genesis File

The genesis file defines the genesis block of the blockchain (that is, the start of the blockchain). The genesis file includes entries for configuring the blockchain such as the mining difficulty and initial accounts and balances.

All nodes in a network must use the same genesis file.

Copy the following genesis definition to a file called privateNetworkGenesis.json and save it in the Private-Network directory:

  "config": {
    "ethash": {
  "nonce": "0x42",
  "gasLimit": "0x1000000",
  "difficulty": "0x10000",
  "alloc": {
    "fe3b557e8fb62b89f4916b721be55ceb828dbd73": {
      "privateKey": "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63",
      "comment": "private key and this comment are ignored.  In a real chain, the private key should NOT be stored",
      "balance": "0xad78ebc5ac6200000"
    "f17f52151EbEF6C7334FAD080c5704D77216b732": {
      "privateKey": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f",
      "comment": "private key and this comment are ignored.  In a real chain, the private key should NOT be stored",
      "balance": "90000000000000000000000"


Do not use the accounts in the genesis file above on mainnet or any public network except for testing. The private keys are displayed so the accounts are not secure.

3. Get Public Key of First Node

To enable nodes to discover each other, a network requires one or more nodes to be bootnodes. For this private network, we will use Node-1 as the bootnode. This requires obtaining the public key for the enode URL.

In the Node-1 directory, use the export-pub-key subcommand to write the node public key to the specified file (publicKeyNode1 in this example):

pantheon --data-path=Node-1-data-path --genesis-file=../privateNetworkGenesis.json public-key export --to=Node-1-data-path/publicKeyNode1
pantheon --data-path=Node-1-data-path --genesis-file=..\privateNetworkGenesis.json public-key export --to=Node-1-data-path\publicKeyNode1

Your node 1 directory now contains:

├── Node-1
    ├── Node-1-data-path
        ├── database
        ├── key
        ├── publicKeyNode1

The database directory contains the blockchain data.

4. Start First Node as Bootnode

Start Node-1 specifying:

pantheon --data-path=Node-1-data-path --genesis-file=../privateNetworkGenesis.json --bootnodes --network-id 123 --miner-enabled --miner-coinbase fe3b557e8fb62b89f4916b721be55ceb828dbd73 --rpc-http-enabled --host-whitelist=*      
pantheon --data-path=Node-1-data-path --genesis-file=..\privateNetworkGenesis.json --bootnodes --network-id 123 --miner-enabled --miner-coinbase fe3b557e8fb62b89f4916b721be55ceb828dbd73 --rpc-http-enabled --host-whitelist=*     


The miner coinbase account is one of the accounts defined in the genesis file.

5. Start Additional Nodes

You need the enode URL for Node-1 to specify Node-1 as the bootnode for Node-2 and Node-3.

The enode URL is enode://<id>@<host:port> where:

  • <id> is the node public key excluding the initial 0x. The node public key for Node-1 was written to publicKeyNode1 in step 3.
  • <host:port> is the host and port the bootnode is listening on for P2P peer discovery. Node-1 is using the default host and port of


If the default host and port are used for P2P peer discovery and the node public key exported is: 0xc35c3ec90a8a51fd5703594c6303382f3ae6b2ecb9589bab2c04b3794f2bc3fc2631dabb0c08af795787a6c004d8f532230ae6e9925cbbefb0b28b79295d615f

The enode URL is: enode://c35c3ec90a8a51fd5703594c6303382f3ae6b2ecb9589bab2c04b3794f2bc3fc2[email protected]

Start another terminal, change to the Node-2 directory and start Node-2 specifying:

pantheon --data-path=Node-2-data-path --genesis-file=../privateNetworkGenesis.json --bootnodes="enode://<node public key ex 0x>@" --network-id 123 --p2p-port=30304      
pantheon --data-path=Node-2-data-path --genesis-file=..\privateNetworkGenesis.json --bootnodes="enode://<node public key ex 0x>@" --network-id 123 --p2p-port=30304      

Start another terminal, change to the Node-3 directory and start Node-3 specifying:

  • Different port to Node-1 and Node-2 for P2P peer discovery.
  • Data directory for Node-3 using the --data-path option.
  • Bootnode, genesis file, and network ID as for Node-2.
pantheon --data-path=Node-3-data-path --genesis-file=../privateNetworkGenesis.json --bootnodes="enode://<node public key ex 0x>@" --network-id 123 --p2p-port30305      
pantheon --data-path=Node-3-data-path --genesis-file=..\privateNetworkGenesis.json --bootnodes="enode://<node public key ex 0x>@" --network-id 123 --p2p-port=30305      

6. Confirm Private Network is Working

Start another terminal, use curl to call the JSON-RPC API net_peerCount method and confirm the nodes are functioning as peers:

curl -X POST --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":1}'

The result confirms Node-1 (the node running the JSON-RPC service) has two peers (Node-2 and Node-3):

  "jsonrpc" : "2.0",
  "id" : 1,
  "result" : "0x2"

Next Steps

Import accounts to MetaMask and send transactions as described in the Private Network Quickstart Tutorial


Pantheon does not implement private key management.

Send transactions using eth_sendRawTransaction to send ether or, deploy or invoke contracts.


Start a node with the --rpc-ws-enabled option and use the RPC Pub/Sub API.

Stop Nodes

When finished using the private network, stop all nodes using Ctrl+C in each terminal window.


To restart the private network in the future, start from 4. Restart First Node as Bootnode.

Questions or feedback? You can discuss issues and obtain free support on Pegasys Pantheon Gitter room.
For paid professional support by PegaSys, contact us at [email protected]