--- title: Private Networks sort_key: B --- This guide explains how to set up a private network of multiple Geth nodes. An Ethereum network is a private network if the nodes are not connected to the main network. In this context private only means reserved or isolated, rather than protected or secure. ### Choosing A Network ID The network ID is an integer number which isolates Ethereum peer-to-peer networks. Connections between blockchain nodes will occur only if both peers use the same genesis block and network ID. Use the `--networkid` command line option to set the network ID used by geth. The main network has ID 1. If you supply your own custom network ID which is different than the main network, your nodes will not connect to other nodes and form a private network. If you're planning to connect to your private chain on the Internet, it's best to choose a network ID that isn't already used. You can find a community-run registry of Ethereum networks at . ### Choosing A Consensus Algorithm While the main network uses proof-of-work to secure the blockchain, Geth also supports the 'clique' proof-of-authority consensus algorithm as an alternative for private networks. We strongly recommend 'clique' for new private network deployments because it is much less resource intensive than proof-of-work. The clique system is also used for several public Ethereum testnets such as [Rinkeby](https://www.rinkeby.io) and [Görli](https://goerli.net). Here are the key differences between the two consensus algorithms available in Geth: Ethash consensus, being a proof-of-work algorithm, is a system that allows open participation by anyone willing to dedicate resources to mining. While this is a great property to have for a public network, the overall security of the blockchain strictly depends on the total amount of resources used to secure it. As such, proof-of-work is a poor choice for private networks with few miners. The Ethash mining 'difficulty' is adjusted automatically so that new blocks are created approximately 12 seconds apart. As more mining resources are deployed on the network, creating a new block becomes harder so that the average block time matches the target block time. Clique consensus is a proof-of-authority system where new blocks can be created by authorized 'signers' only. The clique consenus protocol is specified in [EIP-225][clique-eip]. The initial set of authorized signers is configured in the genesis block. Signers can be authorized and de-authorized using a voting mechanism, thus allowing the set of signers to change while the blockchain operates. Clique can be configured to target any block time (within reasonable limits) since it isn't tied to the difficulty adjustment. [clique-eip]: https://eips.ethereum.org/EIPS/eip-225 ### Creating The Genesis Block Every blockchain starts with the genesis block. When you run Geth with default settings for the first time, it commits the main net genesis to the database. For a private network, you usually want a different genesis block. The genesis block is configured using the _genesis.json_ file. When creating a genesis block, you need to decide on a few initial parameters for your blockchain: - Ethereum platform features enabled at launch (`config`). Enabling protocol features while the blockchain is running requires scheduling a hard fork. - Initial block gas limit (`gasLimit`). Your choice here impacts how much EVM computation can happen within a single block. We recommend using the main Ethereum network as a [guideline to find a good amount][gaslimit-chart]. The block gas limit can be adjusted after launch using the `--miner.gastarget` command-line flag. - Initial allocation of ether (`alloc`). This determines how much ether is available to the addresses you list in the genesis block. Additional ether can be created through mining as the chain progresses. [gaslimit-chart]: https://etherscan.io/chart/gaslimit #### Clique Example This is an example of a genesis.json file for a proof-of-authority network. The `config` section ensures that all known protocol changes are available and configures the 'clique' engine to be used for consensus. Note that the initial signer set must be configured through the `extradata` field. This field is required for clique to work. First create the signer account keys using the [geth account](./managing-your-accounts) command (run this command multiple times to create more than one signer key). ```shell geth account new --datadir data ``` Take note of the Ethereum address printed by this command. To create the initial extradata for your network, collect the signer addresses and encode `extradata` as the concatenation of 32 zero bytes, all signer addresses, and 65 further zero bytes. In the example below, `extradata` contains a single initial signer address, `0x7df9a875a174b3bc565e6424a0050ebc1b2d1d82`. You can use the `period` configuration option to set the target block time of the chain. ```json { "config": { "chainId": 15, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "clique": { "period": 5, "epoch": 30000 } }, "difficulty": "1", "gasLimit": "8000000", "extradata": "0x00000000000000000000000000000000000000000000000000000000000000007df9a875a174b3bc565e6424a0050ebc1b2d1d820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "alloc": { "7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" }, "f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" } } } ``` #### Ethash Example Since ethash is the default consensus algorithm, no additional parameters need to be configured in order to use it. You can influence the initial mining difficulty using the `difficulty` parameter, but note that the difficulty adjustment algorithm will quickly adapt to the amount of mining resources you deploy on the chain. ```json { "config": { "chainId": 15, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "ethash": {} }, "difficulty": "1", "gasLimit": "8000000", "alloc": { "7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" }, "f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" } } } ``` ### Initializing the Geth Database To create a blockchain node that uses this genesis block, run the following command. This imports and sets the canonical genesis block for your chain. ```shell geth init --datadir data genesis.json ``` Future runs of geth using this data directory will use the genesis block you have defined. ```shell geth --datadir data --networkid 15 ``` ### Scheduling Hard Forks As Ethereum protocol development progresses, new Ethereum features become available. To enable these features on your private network, you must schedule a hard fork. First, choose any future block number where the hard fork will activate. Continuing from the genesis.json example above, let's assume your network is running and its current block number is 35421. To schedule the 'Istanbul' fork, we pick block 40000 as the activation block number and modify our genesis.json file to set it: ```json { "config": { ... "istanbulBlock": 40000, ... }, ... } ``` In order to update to the new fork, first ensure that all Geth instances on your private network actually support the Istanbul fork (i.e. ensure you have the latest version of Geth installed). Now shut down all nodes and re-run the `init` command to enable the new chain configuration: ```shell geth init --datadir data genesis.json ``` ### Setting Up Networking Once your node is initialized to the desired genesis state, it is time to set up the peer-to-peer network. Any node can be used as an entry point. We recommend dedicating a single node as the rendezvous point which all other nodes use to join. This node is called the 'bootstrap node'. First, determine the IP address of the machine your bootstrap node will run on. If you are using a cloud service such as Amazon EC2, you'll find the IP of the virtual machine in the management console. Please also ensure that your firewall configuration allows both UDP and TCP traffic on port 30303. The bootstrap node needs to know about its own IP address in order to be able to relay it others. The IP is set using the `--nat` flag (insert your own IP instead of the example address below). ```shell geth --datadir data --networkid 15 --nat extip:172.16.254.4 ``` Now extract the 'node record' of the bootnode using the JS console. ```shell geth attach data/geth.ipc --exec admin.nodeInfo.enr ``` This command should print a base64 string such as the following example. Other nodes will use the information contained in the bootstrap node record to connect to your peer-to-peer network. ```text "enr:-Je4QEiMeOxy_h0aweL2DtZmxnUMy-XPQcZllrMt_2V1lzynOwSx7GnjCf1k8BAsZD5dvHOBLuldzLYxpoD5UcqISiwDg2V0aMfGhGlQhqmAgmlkgnY0gmlwhKwQ_gSJc2VjcDI1NmsxoQKX_WLWgDKONsGvxtp9OeSIv2fRoGwu5vMtxfNGdut4cIN0Y3CCdl-DdWRwgnZf" ``` Setting up peer-to-peer networking depends on your requirements. If you connect nodes across the Internet, please ensure that your bootnode and all other nodes have public IP addresses assigned, and both TCP and UDP traffic can pass the firewall. If Internet connectivity is not required or all member nodes connect using well-known IPs, we strongly recommend setting up Geth to restrict peer-to-peer connectivity to an IP subnet. Doing so will further isolate your network and prevents cross-connecting with other blockchain networks in case your nodes are reachable from the Internet. Use the `--netrestrict` flag to configure a whitelist of IP networks: ```shell geth --netrestrict 172.16.254.0/24 ``` With the above setting, Geth will only allow connections from the 172.16.254.0/24 subnet, and will not attempt to connect to other nodes outside of the set IP range. ### Running Member Nodes Before running a member node, you have to initialize it with the same genesis file as used for the bootstrap node. With the bootnode operational and externally reachable (you can try `telnet ` to ensure it's indeed reachable), you can start more Geth nodes and connect them via the bootstrap node using the `--bootnodes` flag. To create a member node running on the same machine as the bootstrap node, choose a separate data directory (example: `data-2`) and listening port (example: `30305`): ```shell geth --datadir data-2 --networkid 15 --port 30305 --bootnodes ``` With the member node running, you can check whether it is connected to the bootstrap node or any other node in your network by attaching a console and running `admin.peers`. It may take up to a few seconds for the nodes to get connected. ```shell geth attach data-2/geth.ipc --exec admin.peers ``` ### Clique: Running A Signer To set up Geth for signing blocks in proof-of-authority mode, a signer account must be available. The account must be unlocked to mine blocks. The following command will prompt for the account password, then start signing blocks: ```shell geth --unlock 0x7df9a875a174b3bc565e6424a0050ebc1b2d1d82 --mine ``` You can further configure mining by changing the default gas limit blocks converge to (with `--miner.gastarget`) and the price transactions are accepted at (with `--miner.gasprice`). ### Ethash: Running A Miner For proof-of-work in a simple private network, a single CPU miner instance is enough to create a stable stream of blocks at regular intervals. To start a Geth instance for mining, run it with all the usual flags and add the following to configure mining: ```shell geth --mine --miner.threads=1 --miner.etherbase=0x0000000000000000000000000000000000000000 ``` This will start mining bocks and transactions on a single CPU thread, crediting all block rewards to the account specified by `--miner.etherbase`.