Running a standalone private Geth node for non production purpose


Running a standalone private Geth node for non-production purpose

Importing pre-defined keys with enough pre-allocated balances in minimum steps.

Photos by XPS from Unsplash


A simple Ethereum node is necessary for test or proof-of-concept purpose. Although there are well-known Ganache or Ganache CLI (formally named TestRPC), sometimes you may want Geth in test or more earlier environment.

One of the most expensive tasks with Ethereum network is to keep accounts secure(protecting private keys against compromise or exposure). But in non production environment, security requirements for the accounts are not so high, but rather using pre-defined keys which are not secure at all is preferred to make tasks for providing initial balances more simple and programmable. In these cases, the following features are favorable.

  • Pre-defined accounts are created using pre-defined keys automatically.
  • Pre-defined accounts are unlocked automatically from the start.
  • Pre-defined accounts have huge balances. (to fund enough ether to application-specific accounts later)
  • Fewer nodes or even just a single node are/is enough.

Geth is the most widely spread Ethereum client software providing many powerful features. These features seems to focus more on production environment and so it would be rather complicated to apply above non production oriented requirements.
For Ganache CLI, just using --account and --unlock options, you can meet the above requirements.
Although it is not so simple for Geth, you can still comply those requirements using script preload and genesis configuration.

Prepare Keys

The following shows 5 private keys and corresponding addresses used later. For development or testing environment, using pre-defined keys could be no problem or even profitable.
You can easily get new keys and addresses through online generators or libraries like eth-account in Python.

[ ba75c5fd16ae1151dc9f961e94e219994c6335a5b4148c624142243fb76306d6,
d3ae0500e21008c89ca4746be7522340c67f5730 ],
[ 097dd6aedb87b3b5e541cfb9ef8d4beb7a66084dd80d99c2e51aeabeae320980,
76aaacd6169017644ba7530b7d956e1fcc0178ad ],
[ abae82647f5881a398f7eede8910803d65470a7cbaee9ddda90dcdcdc8dcdacf,
eb875bb0eec43d779c4d539ca34e89fb0868d867 ],
[ cc1af47cbc9de0c9a1e1049c1a62ddb9e08440d16093803d74e93f1cea3458ee,
0ccca39f9c169996c8380bf7c529dc3b9ff6198a ],
[ 3e48c4e748b8f5baf6f870c5c4d2a0147390c94e778a9ca67de945bffeb2f72a,
d738b71007cffbec9b0a7e99088b132858f5e270 ],

Generate Genesis Block

For Geth, before starting a new network (even a private network with a single node) a genesis block should be created using genesis configuration like the following.

The genesis configuration can define prepaid balances to specific accounts. The below configuration would allocate 10²² wei for each account previously prepared.
The configuration just supplies balances but doesn’t create those account at server side. You can later create these accounts on the server or on the client such as MetaMask. Even they are already created elsewhere. Anyway those accounts would have huge balances in this network.

"config": {
"chainId": 2021,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirglacierblock": 0,
"ethash": {
"fixeddifficulty": 100
"nonce": "0x0",
"difficulty": "0x60",
"gasLimit": "0x1fffffffffffff",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
{ "balance": "10000000000000000000000" },
{ "balance": "10000000000000000000000" },
{ "balance": "10000000000000000000000" },
{ "balance": "10000000000000000000000" },
{ "balance": "10000000000000000000000" }

To generate a genesis block, execute geth init command. The command will just create a genesis block without launching server process.

$ geth --datadir ./data init genesis.json

Launch Standalone Geth Node

Initial balances are allocated, so creating accounts on the server and unlocking them are left. Even in testing environment, unlocking several accounts with huge balances can cause unintentional trouble , especially for projects with large members. But, it could be much convenient when developing and testing. Furthermore if the network deals with ether only for gas, not for currency, these balances would not make serious problems.
Of course, these accounts should be used only to distribute necessary ether to other accounts for applications. Pre-defined accounts are not expected to be directly used as an application accounts which may have special roles and privileges on smart contracts.

Geth doesn’t provide command line options to import keys/accounts automatically, although it has --unlock option and -password option to unlock accounts already created. All these conditions make it difficult to import accounts and unlock them automatically.
But, there’s a way to execute scripts when launching Geth using --preload or --exec option.

Below is a script importing keys, unlocking accounts and then starting a miner thread with the first account. The script makes use of Geth’s console API including personal.listAccounts, personal.importRawKey(), personal.unlockAccount(), miner.setEtherbase(), miner.start() functions. These are Geth’s native functions that can be used in Geth console with less typing than standard web3.js.

personal.importRawKey() function imports specified key and creates a new account with it. This is persistent and so enough to be called once. But, personal.unlockAccount() is not persistent but valid only under the current Geth instance. So, unlocks need to be called whenever a Geth process is started.

As of version 1.9, Geth console is based on pure Go implementation of ECMAScript 5.1. So, recent features of ECMAScript such as await/async statements, let/const statements, and for...of loop are not included yet.

Below command line would launch a standalone Geth instance pre-processing the above script.

$ geth --datadir ./data --nodiscover --verbosity 2 --maxpeers 0 \
--allow-insecure-unlock \
--preload ./scripts/geth-setup-accounts.js \
--http --http.addr localhost --http.port 8545 \
console >> geth.log 2>&1

Quick Test

After a Geth instance started, you can access the process from the other terminals via geth attach command.

Below is a quick test showing everything works as expected. When repeating yourself, a little time would be necessary after transactions are sent.

Running a standalone private Geth node for non production purpose was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.