299 lines
12 KiB
Markdown
299 lines
12 KiB
Markdown
---
|
|
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 <https://chainid.network>.
|
|
|
|
### Choosing A Consensus Algorithm
|
|
|
|
While the main network uses proof-of-work to secure the blockchain, Geth also supports the
|
|
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 <other-flags> --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 <ip> <port>`
|
|
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 <bootstrap-node-record>
|
|
```
|
|
|
|
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 <other-flags> --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 <other-flags> --mine --miner.threads=1 --etherbase=0x0000000000000000000000000000000000000000
|
|
```
|
|
|
|
This will start mining bocks and transactions on a single CPU thread, crediting all block
|
|
rewards to the account specified by `--etherbase`.
|