13 KiB
Creating a Private Network using IBFT 2.0 (Proof of Authority) Consensus Protocol
A private network provides a configurable network for testing. This private network uses the IBFT 2.0 (Proof of Authority) consensus protocol.
!!!important 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.
Prerequisites
Curl (or similar web service client)
Steps
To create a private network using IBFT 2.0 with three nodes and one initial validator:
- Create Folders
- Get Public Key for Node-1
- Get Node Addresses
- Create JSON File to RLP Encode
- RLP Encode Extra Data
- Create Genesis File
- Delete Database Directory
- Start First Node as Bootnode
- Start Node-2
- Start Node-3
- Confirm Private Network is 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:
IBFT-Network/
├── Node-1
│ ├── data
├── Node-2
│ ├── data
└── Node-3
├── data
2. Get Public Key for Node-1
The public key of Node-1 is needed for the enode URL. The enode URL is used when starting Node-2 and Node-3 to specify Node-1 is the bootnode.
In the Node-1
directory, use the public-key export
subcommand to write
the node public key to the specified file (publicKey
):
pantheon --data-path=data public-key export --to=data/publicKey
pantheon --data-path=path public-key export --to=data\publicKey
!!!note
The --data-path
option is not used when running Pantheon
from the Docker image. Use a volume to specify the data directory.
Your node 1 directory now contains:
├── Node-1
├── data
├── database
├── key
├── publicKey
The database
directory contains the blockchain data.
3. Get Node Addresses
In IBFT 2.0 networks, the address of at least one initial validator must be included in the genesis file in the
RLP encoded extraData
string. For this network, we will use Node-1 as the initial validator. This requires obtaining the address for Node-1.
To obtain the address for Node-1, in the Node-1
directory, use the public-key export-address
subcommand to write the node address to the specified file (nodeAddress
)
pantheon --data-path=data public-key export-address --to=data/nodeAddress
pantheon --data-path=data public-key export-address --to=data\nodeAddress
To vote in validators once the network is running, the node address for the proposed validator is required. In the Node-2
and Node-3
directories, write the node address for each node to the specified file using the public-key export-address
command as for Node-1
.
4. Create JSON File to RLP Encode
Create a file called toEncode.json
in the IBFT-Network
directory that contains the Node 1 address excluding the 0x prefix
from the nodeAddress
file in the Node-1/data
directory:
[
"<Node 1 Address>"
]
[
"9b9f91039843450927b0043ae71cd803e0db0c30"
]
5. RLP Encode Extra Data
The extraData
property in IBFT 2.0 genesis files is an RLP encoding of [32 Bytes Vanity, List<Validators>, No Vote, Round=Int(0), 0 Seals]
.
In the IBFT-Network
directory, use the Pantheon subcommand rlp encode
to generate the extraData
RLP string to include in the genesis file.
pantheon rlp encode --from=toEncode.json --to=rlpEncodedExtraData
pantheon rlp encode --from=toEncode.json --to=rlpEncodedExtraData
6. Create Genesis File
The genesis file defines the genesis block of the blockchain (that is, the start of the blockchain).
The IBFT 2.0 genesis file includes the address of Node-1 as the initial validator in the
RLP encoded extraData
string.
All nodes in a network must use the same genesis file.
Copy the following genesis definition to a file called ibftGenesis.json
and save it in the IBFT-Network
directory:
{
"config": {
"chainId": 1981,
"constantinoplefixblock": 0,
"ibft2": {
"blockperiodseconds": 2,
"epochlength": 30000,
"requesttimeoutseconds": 10
}
},
"nonce": "0x0",
"timestamp": "0x58ee40ba",
"extraData": "<RLP Encoded Extra Data>",
"gasLimit": "0x47b760",
"difficulty": "0x1",
"mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
"coinbase": "0x0000000000000000000000000000000000000000",
"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"
},
"627306090abaB3A6e1400e9345bC60c78a8BEf57": {
"privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3",
"comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored",
"balance": "90000000000000000000000"
},
"f17f52151EbEF6C7334FAD080c5704D77216b732": {
"privateKey": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f",
"comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored",
"balance": "90000000000000000000000"
}
}
}
In extraData
, copy the RLP encoded data from the rlpEncodedExtraData
file.
!!! example
```json
{
...
"extraData":0xf83ea00000000000000000000000000000000000000000000000000000000000000000d5949b9f91039843450927b0043ae71cd803e0db0c30808400000000c0",
...
}
```
!!! warning
Do not use the accounts in alloc
in the genesis file on mainnet or any public network except for testing.
The private keys are displayed which means the accounts are not secure.
7. Delete Database Directories
Delete the database
directories created when getting the public key for Node-1 and addresses for Node-2 and Node-3.
The nodes cannot be started with the IBFT 2.0 genesis file while the previously generated data is in the database
directories.
8. Start First Node as Bootnode
In the Node-1
directory, start Node-1:
pantheon --data-path=data --genesis-file=../ibftGenesis.json --rpc-http-enabled --rpc-http-api=ETH,NET,IBFT --host-whitelist=* --rpc-http-cors-origins="all"
pantheon --data-path=data --genesis-file=..\ibftGenesis.json --rpc-http-enabled --rpc-http-api=ETH,NET,IBFT --host-whitelist=* --rpc-http-cors-origins="all"
!!!note
The --genesis-file
option is not used when running
Pantheon from the Docker image. Use a bind mount to
specify a configuration file with Docker.
The command line specifies:
- Data directory for Node-1 using the
--data-path
option. - JSON-RPC API is enabled using the
--rpc-http-enabled
option - ETH,NET, and IBFT APIs are enabled using the
--rpc-http-api
option - All hosts can access the HTTP JSON-RPC API using the
--host-whitelist
option - All domains can access the node using the HTTP JSON-RPC API using the
--rpc-http-cors-origins
option
9. Start Node-2
You need the enode URL for Node-1 to specify Node-1 as a bootnode.
Start another terminal, change to the Node-2
directory and start Node-2 replacing the enode URL with your bootonde:
pantheon --data-path=data --genesis-file=../ibftGenesis.json --bootnodes="enode://<node public key ex 0x>@127.0.0.1:30303" --p2p-port=30304 --rpc-http-enabled --rpc-http-api=ETH,NET,IBFT --host-whitelist=* --rpc-http-cors-origins="all" --rpc-http-port=8546
pantheon --data-path=data --genesis-file=..\ibftGenesis.json --bootnodes="enode://<node public key ex 0x>@127.0.0.1:30303" --p2p-port=30304 --rpc-http-enabled --rpc-http-api=ETH,NET,IBFT --host-whitelist=* --rpc-http-cors-origins="all" --rpc-http-port=8546
The command line specifies:
- Data directory for Node-2 using the
--data-path
option. - Different port to Node-1 for P2P peer discovery using the
--p2p-port
option. - Different port to Node-1 for HTTP JSON-RPC using the
--rpc-http-port
option. - Enode URL for Node-1 using the
--bootnodes
option. - Other options as for Node-1.
10. Start Node-3
Start another terminal, change to the Node-3
directory and start Node-3 replacing the enode URL with your bootnode:
pantheon --data-path=data --genesis-file=../ibftGenesis.json --bootnodes="enode://<node public key ex 0x>@127.0.0.1:30303" --p2p-port=30305 --rpc-http-enabled --rpc-http-api=ETH,NET,IBFT --host-whitelist=* --rpc-http-cors-origins="all" --rpc-http-port=8547
pantheon --data-path=data --genesis-file=..\ibftGenesis.json --bootnodes="enode://<node public key ex 0x>@127.0.0.1:30303" --p2p-port=30305 --rpc-http-enabled --rpc-http-api=ETH,NET,IBFT --host-whitelist=* --rpc-http-cors-origins="all" --rpc-http-port=8547
The command line specifies:
- Data directory for Node-3 using the
--data-path
option. - Different port to Node-1 and Node-2 for P2P peer discovery using the
--p2p-port
option. - Different port to Node-1 and Node-2 for HTTP JSON-RPC using the
--rpc-http-port
option. - Bootnode as for Node-2.
- Other options as for Node-1.
11. 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}' localhost:8545
The result confirms Node-1 has two peers (Node-2 and Node-3):
{
"jsonrpc" : "2.0",
"id" : 1,
"result" : "0x2"
}
Next Steps
Look at the logs displayed to confirm Node-1 is producing blocks and Node-2 and Node-3 are importing blocks.
Use the IBFT API to add Node-2 or Node-3 as a validator.
!!! note To add Node-2 or Node-3 as a validator you need the node address as when specifying Node-1 as the initial validator.
Import accounts to MetaMask and send transactions as described in the Private Network Quickstart Tutorial
!!! info Pantheon does not implement private key management.
Stop Nodes
When finished using the private network, stop all nodes using ++ctrl+c++ in each terminal window.
!!!tip To restart the IBFT 2.0 network in the future, start from 8. Start First Node as Bootnode.