This page will walk you through the process of deploying a private Ethereum Network.
Before we can deploy the network, we need to install some necessary software.
Install dependencies first.
sudo apt update && sudo apt upgrade && sudo apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common
Now, we'll need to get our aptitude sources updated to include the Docker-CE repository.
Now, we'll need to get our aptitude sources updated to include the Docker-CE repository.
These commands must be run as root.
sudo su
curl -fsSL
https://download.docker.com/linux/debian/gpg
| apt-key add -
add-apt-repository "deb [arch=amd64]
https://download.docker.com/linux/debian
$(lsb_release -cs) stable"
Once we have added the repo and the necessary key, we want to exit the root user. exit
Once we have added the repo and the necessary key, we want to exit the root user. exit
$
if you're a non-root user. If you're in an elevated (root) TTY session, your shell prompt will display a #
Since we've modified our aptitude sources, we'll need to update them before we can install docker-ce
sudo apt update && sudo apt install docker-ce
Now that we have Docker-CE installed, we'll need to add our user to the docker group.
Now that we have Docker-CE installed, we'll need to add our user to the docker group.
(The prevents us from having to run docker commands with elevated (root) permissions)
sudo usermod -aG docker $USER
Lastly, we'll install docker-compose
sudo curl -L "
https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname
-s)-$(uname -m)" -o /usr/local/bin/docker-compose
We need to create some configuration files and place them into specific directories before we can do anything else.
The following is a working example for a network running on a ChainID of 123456
.
Please feel free to modify any of the following as you see fit.
localNet/
├── docker-compose.yml
├── genesis
│ └── pow_genesis.json
└── geth-data
├── geth
├── keystore
└── password.txt
To get the above directory structure started, we'll run the following commands from your $HOME
directory
mkdir -p ~/localNet/genesis
We will create the necessary pow-genesis.json file in the genesis directory.
mkdir ~/localNet/geth-data
The geth-data directory will contain all of the state data for our local network.
Now that we have the directories created, we now need to generate an account before we can do much else.
Deploy a geth container, connect to the console, and generate an account
docker run -it --rm -v $(pwd)/geth-data:/geth-data ethereum/client-go:stable --datadir /geth-data account new
This will prompt you for a password.
Please remember what your password is, because we'll be creating a password.txt file in the next step.
After entering your password, you'll be provided with an address. We'll use this address for the following variables (so copy it down somewhere):
docker-compose.yml:
--unlock
--miner.etherbase
pow_genesis.json:
alloc
With the directories and Ethereum account created, let's create the necessary files.
NOTE: In the below example, you can adjust the chainId
to whatever value you prefer (as long as it's not larger than 18,446,744,073,709,551,615).
NOTE: Please update the alloc
address (example value is 0xYour_Address_here
) to the address we created above.
nano ~/localNet/genesis/pow_genesis.json
{
"config": {
"chainId": 123456,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirGlacierBlock": 0,
"berlinBlock": 0
},
"nonce": "0x0",
"timestamp": "0x5f5b9800",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760",
"difficulty": "0x80000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"0xYour_Address_here": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
}
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
Now that we've created our pow_genesis.json file, we need to create our docker-compose.yml file.
NOTE: Please be sure to update the --miner.etherbase
and --unlock
values with the same address that we used for the alloc
section above
nano ~/localNet/docker-compose.yml
version: '3.7'
services:
geth:
image: ethereum/client-go:stable
volumes:
- ./geth-data:/geth-data
- ./genesis:/genesis
ports:
- "8545:8545"
- "30303:30303"
command: >
--datadir /geth-data
--ipcdisable
--http
--http.addr 0.0.0.0
--http.port 8545
--http.api admin,eth,net,web3,personal,miner
--http.corsdomain "*"
--ws
--ws.addr 0.0.0.0
--ws.port 8546
--ws.api admin,eth,net,web3,personal,miner
--ws.origins "*"
--networkid 12345
--syncmode full
--gcmode archive
--cache 1024
--mine
--miner.etherbase 0xYour_Address_here
--miner.gasprice 0
--unlock 0xYour_Address_here
--password /geth-data/password.txt
--allow-insecure-unlock
--nodiscover
With the necessary directories, files, and address created, we can initialize and deploy our private Ethereum network.
We need to initialize our network with the pow_genesis.json configuration first, then we can deploy our node.
The following command will run an geth container to execute the commands to create the necessary files in your geth-data directory, based on your pow_genesis.json configuration. The container will then be removed.
docker run --rm -v $(pwd)/geth-data:/geth-data -v $(pwd)/genesis:/genesis ethereum/client-go:stable --datadir /geth-data init /genesis/pow_genesis.json
With the network initialized, we can now run our Ethereum node.
The following command will deploy the container in a detatched state. If you want to see the logs, you can do so via the docker logs
command.
docker-compose up -d
With the container running, we can create a bash script to check the status of the network.
You can create a shell script and copy the below into it.
nano checkNetworkStatus.sh
#!/bin/bash
JSON_RPC_URL="http://localhost:8545"
# Prepare JSON-RPC request payload
REQUEST_DATA='{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}'
# Send JSON-RPC request to Ethereum node
RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" --data "$REQUEST_DATA" $JSON_RPC_URL)
# Check if the response contains the expected result field
if [[ $RESPONSE == *'"result":'* ]]; then
echo "Ethereum JSON-RPC endpoint is working correctly."
else
echo "Ethereum JSON-RPC endpoint is not working."
fi
# Check RPC Endpoint Chain ID:
CHAIN_ID=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' http://localhost:8545 | jq -r)
echo "Chain ID: $((CHAIN_ID))"
If we make it executable, chmod +x checkNetworkStatus.sh
We can then run it with ./checkNetworkStatus.sh
We should see output similar to below:
Ethereum JSON-RPC endpoint is working correctly.
Chain ID: 123456
With the network created, we can connect our metamask to the RPC endpoint.
If we want to play around on our private network, we can add it to MetaMask.
Go to the Add Network page of MetaMask and add the following values:
NOTE: These are just examples.
Network name:privateNetwork
New RPC Endpoint:
http://local_ip_address:8545
Chain ID:
123456
Currency symbol:fake
Block Explorer URL:
you can leave this blank
With our network added to MetaMask, we can now import our account and have darn near unlimited testnet tokens.
When we created our account, it should have created a file in the following location:
localNet/
└── geth-data
└── keystore
└── UTC--YEAR-MONTH-DATE_TIME--address
if you copy the contents of that into a properly formatted json file, we can import that json file into MetaMask
sudo more ~/localNet/geth-data/keystore/UTC--REST_OF_FILE_NAME | jq
Example output:
{
"address": "0000000000000000000000000000000000000000",
"crypto": {
"cipher": "aes-128-ctr",
"ciphertext": "OMITTED",
"cipherparams": {
"iv": "OMITTED"
},
"kdf": "scrypt",
"kdfparams": {
"dklen": 32,
"n": 262144,
"p": 1,
"r": 8,
"salt": "OMITED"
},
"mac": "OMITED"
},
"id": "OMITTED",
"version": 3
}
Copy the output of that command into a .json
file.
Then open MetaMask and click the circle icon in the top right > Import Account > Select type > json file > select your json file and enter your password.