mirror of https://github.com/ethereum/go-ethereum
[DOCS] bring back the 'Private Network' page (#20262)
This improves the private network page. We now recommend using clique instead of ethash. The networking section is improved as well and now recommends using a regular geth node for bootstrapping instead of running cmd/bootnode. I also added some text about the --netrestrict option.pull/20303/head
parent
76bc99158d
commit
a89f10fcdd
@ -0,0 +1,295 @@ |
|||||||
|
--- |
||||||
|
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://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-char). The block gas limit can be adjusted |
||||||
|
after launch using the `--targetgaslimit` 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 |
||||||
|
|
||||||
|
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 `--targetgaslimit`) and the price transactions are accepted at (with `--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 --minerthreads=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`. |
@ -1,108 +0,0 @@ |
|||||||
--- |
|
||||||
title: Private network |
|
||||||
--- |
|
||||||
An Ethereum network is a private network if the nodes are not connected to the main |
|
||||||
network nodes. In this context private only means reserved or isolated, rather than |
|
||||||
protected or secure. |
|
||||||
|
|
||||||
## Choosing A Network ID |
|
||||||
|
|
||||||
Since connections between nodes are valid only if peers have identical protocol version |
|
||||||
and network ID, you can effectively isolate your network by setting either of these to a |
|
||||||
non default value. We recommend using the `--networkid` command line option for this. Its |
|
||||||
argument is an integer, the main network has id 1 (the default). So 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. |
|
||||||
|
|
||||||
## Creating The Genesis Block |
|
||||||
|
|
||||||
Every blockchain starts with the genesis block. When you run geth with default settings |
|
||||||
for the first time, the main net genesis block is committed to the database. For a private |
|
||||||
network, you usually want a different genesis block. |
|
||||||
|
|
||||||
Here's an example of a custom genesis.json file. The `config` section ensures that certain |
|
||||||
protocol upgrades are immediately available. The `alloc` section pre-funds accounts. |
|
||||||
|
|
||||||
```json |
|
||||||
{ |
|
||||||
"config": { |
|
||||||
"chainId": 15, |
|
||||||
"homesteadBlock": 0, |
|
||||||
"eip155Block": 0, |
|
||||||
"eip158Block": 0 |
|
||||||
}, |
|
||||||
"difficulty": "200000000", |
|
||||||
"gasLimit": "2100000", |
|
||||||
"alloc": { |
|
||||||
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" }, |
|
||||||
"f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" } |
|
||||||
} |
|
||||||
} |
|
||||||
``` |
|
||||||
|
|
||||||
To create a database that uses this genesis block, run the following command. This will |
|
||||||
import and set the canonical genesis block for your chain. |
|
||||||
|
|
||||||
```text |
|
||||||
geth --datadir path/to/custom/data/folder init genesis.json |
|
||||||
``` |
|
||||||
|
|
||||||
Future runs of geth on this data directory will use the genesis block you have defined. |
|
||||||
|
|
||||||
```text |
|
||||||
geth --datadir path/to/custom/data/folder --networkid 15 |
|
||||||
``` |
|
||||||
|
|
||||||
## Network Connectivity |
|
||||||
|
|
||||||
With all nodes that you want to run initialized to the desired genesis state, you'll need |
|
||||||
to start a bootstrap node that others can use to find each other in your network and/or |
|
||||||
over the internet. The clean way is to configure and run a dedicated bootnode: |
|
||||||
|
|
||||||
```text |
|
||||||
bootnode --genkey=boot.key |
|
||||||
bootnode --nodekey=boot.key |
|
||||||
``` |
|
||||||
|
|
||||||
With the bootnode online, it will display an enode URL that other nodes can use to connect |
|
||||||
to it and exchange peer information. Make sure to replace the displayed IP address |
|
||||||
information (most probably [::]) with your externally accessible IP to get the actual |
|
||||||
enode URL. |
|
||||||
|
|
||||||
Note: You can also use a full fledged Geth node as a bootstrap node. |
|
||||||
|
|
||||||
### Starting Up Your Member Nodes |
|
||||||
|
|
||||||
With the bootnode operational and externally reachable (you can try `telnet <ip> <port>` |
|
||||||
to ensure it's indeed reachable), start every subsequent Geth node pointed to the bootnode |
|
||||||
for peer discovery via the --bootnodes flag. It will probably also be desirable to keep |
|
||||||
the data directory of your private network separated, so do also specify a custom |
|
||||||
`--datadir` flag. |
|
||||||
|
|
||||||
```text |
|
||||||
geth --datadir path/to/custom/data/folder --networkid 15 --bootnodes <bootnode-enode-url-from-above> |
|
||||||
``` |
|
||||||
|
|
||||||
Since your network will be completely cut off from the main and test networks, you'll also |
|
||||||
need to configure a miner to process transactions and create new blocks for you. |
|
||||||
|
|
||||||
## Running A Private Miner |
|
||||||
|
|
||||||
Mining on the public Ethereum network is a complex task as it's only feasible using GPUs, |
|
||||||
requiring an OpenCL or CUDA enabled ethminer instance. For information on such a setup, |
|
||||||
please consult the EtherMining subreddit and the Genoil miner repository. |
|
||||||
|
|
||||||
In a private network setting however, a single CPU miner instance is more than enough for |
|
||||||
practical purposes as it can produce a stable stream of blocks at the correct intervals |
|
||||||
without needing heavy resources (consider running on a single thread, no need for multiple |
|
||||||
ones either). To start a Geth instance for mining, run it with all your usual flags, |
|
||||||
extended by: |
|
||||||
|
|
||||||
```text |
|
||||||
$ geth <usual-flags> --mine --minerthreads=1 --etherbase=0x0000000000000000000000000000000000000000 |
|
||||||
``` |
|
||||||
|
|
||||||
Which will start mining bocks and transactions on a single CPU thread, crediting all |
|
||||||
proceedings to the account specified by --etherbase. You can further tune the mining by |
|
||||||
changing the default gas limit blocks converge to (`--targetgaslimit`) and the price |
|
||||||
transactions are accepted at (`--gasprice`). |
|
Loading…
Reference in new issue