How to setup your own private Ethereum node on macOS
Information
Ethereum is an open-source, public, blockchain-based distributed computing platform featuring smart contract (scripting)
functionality. It provides a decentralized virtual machine, the Ethereum Virtual Machine (EVM).
This virtual machine can execute Turing-complete scripts using an international network of public nodes and a
token called ether. Gas is used to prevent spam on the network and allocate resources proportionally to the
incentive offered by the request.
The Ethereum homepage can be found at: https://www.ethereum.org/
The latest Ethereum documentation can be found at: http://ethdocs.org/en/latest/
The latest Solidity documentation can be found at: https://solidity.readthedocs.io/en/develop/
The latest Ethereum source code can be downloaded from: https://github.com/ethereum
Operating system used
macOS 10.12 Sierra
Software prerequisites
Ethereum
Procedure
- Setup your own private Ethereum node. Create the following folders:
Type: mkdir ~/tools
Type: mkdir ~/tools/ethereum_private_network
Type: mkdir ~/tools/ethereum_private_network/datadir
- I assume you already have Geth installed. Now create 5 accounts, type:
geth --datadir /Users/robertlie/tools/ethereum_private_network/datadir account new
You will see:
WARN [06-19|12:06:31] No etherbase set and no accounts found as default
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: mysecret1
Repeat passphrase: mysecret1
Address: {de1c70cc1cbcaafdfa6d4593c37cbeb6ed5306d0}
The folder ~/tools/ethereum_private_network/datadir/keystore now contains a file.
The file contains the public and private key, the password is not stored!
An example of such a file:
UTC--2017-06-19T11-12-59.520967006Z-- de1c70cc1cbcaafdfa6d4593c37cbeb6ed5306d0
This particular file contains the following:
{
"address":"de1c70cc1cbcaafdfa6d4593c37cbeb6ed5306d0",
"crypto":{
"cipher":"aes-128-ctr",
"ciphertext":
"dadedafd8f8da097793f547f917a2a7c86a6 db8a3a69935274f373d62cdee1a0",
"cipherparams":{"iv": "545424c30e885389ca8ca63f33676b0d"},
"kdf":"scrypt",
"kdfparams": {
"dklen":32,
"n":262144,
"p":1,
"r":8,
"salt":"
25a990282b875b397504d30bc19c230 4752bfa1ff0f136e062a9845e29649235"
},
"mac":"46fe509470da32a2a20f1fdf4486444fcf 48ed67987c680cd9ca9d9debcf17ad"},
"id":"9302e4fe-c5c1-4744-9383-8428bb3147cb",
"version":3
}
If you do not specify the "--datadir" parameter a default keystore is created in:
<homedir>/Library/Ethereum/keystore
Repeat this command 4 more times:
16378b0cdb2719c9bfc8540878d7f116bbed9c22 - password: mysecret2
c45ae2b9bfae491c79462aaad05fb4b77e7091f2 - password: mysecret3
549a763482f6c10550c02c865d6b9e7ab0d24eac - password: mysecret4
6edb33e54bdcb55eb520c7e204a43217b9230966 - password: mysecret5
- Create a ~/tools/ethereum_private_network/genesis_private_network.json file.
{
"config": {
"chainId": 987654321,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"difficulty": "0x400",
"gasLimit": "0x8000000",
"alloc": {}
}
- config
Configuration to describe the chain itself. Specifically the chain ID, the consensus engines
to use, as well as the block numbers of any relevant hard forks.
chainId
Identifies the current chain and is used for replay protection.
You should set it to a unique value for your private chain.
homesteadBlock
Your chain won't be undergoing the switch to Homestead, so leave this as 0.
eip155Block
Your chain won't be hard-forking for these changes, so leave as 0.
eip158Block
your chain won't be hard-forking for these changes, so leave as 0.
- difficulty
A scalar value corresponding to the difficulty level applied during the nonce discovering of this block.
It defines the mining Target, which can be calculated from the previous block’s difficulty level and the
timestamp. The higher the difficulty, the statistically more calculations a Miner must perform to discover
a valid block. This value is used to control the Block generation time of a Blockchain,
keeping the Block generation frequency within a target range. On the test network,
we keep this value low to avoid waiting during tests, since the discovery of a valid Block is
required to execute a transaction on the Blockchain.
- gasLimit
A scalar value equal to the current chain-wide limit of Gas expenditure per block.
High in our case to avoid being limited by this threshold during tests.
Note: this does not indicate that we should not pay attention to the Gas consumption
of our Contracts.
- alloc
Allows defining a list of pre-filled wallets. That’s an Ethereum specific functionality to handle the
“Ether pre-sale” period. Since we can mine local Ether quickly, we don’t use this option.
Coinbase the 160-bit address to which all rewards (in Ether) collected from the successful mining of
this block have been transferred. They are a sum of the mining reward itself and the Contract transaction
execution refunds. Often named “beneficiary” in the specifications, sometimes “etherbase” in the online
documentation. This can be anything in the Genesis Block since the value is set by the setting of the
Miner when a new Block is created.
- Modify the genesis_private_network.json file.
- Change the "alloc" parameter.
You can pre-allocate ethers to your 5 accounts.
In my example 20 ether (= 0x1158e460913d00000 wei) is allocated for each account.
- Change the "chainId" parameter.
Replace 987654321 with your arbitrary chosen number.
See my modified ~/tools/ethereum_private_network/genesis_private_network.json file.
- Create a ~/tools/ethereum_private_network/Makefile file.
- Initialize the blockchain from the genesis_private_network.json file.
Type: cd ~/tools/ethereum_private_network
Type: make init
You will see:
geth --datadir /Users/robertlie/tools/ethereum_private_network/datadir init
/Users/robertlie/tools/ ethereum_private_network/genesis_private_network.json
INFO [06-19|13:36:54] Allocated cache and file handles
database=/Users/robertlie/tools/ ethereum_private_network/datadir/geth/chaindata cache=16 handles=16
INFO [06-19|13:36:54] Writing custom genesis block
INFO [06-19|13:36:54] Successfully wrote genesis state database=chaindata hash=ea3061…dd0ee5
INFO [06-19|13:36:54] Allocated cache and file handles database=/Users/robertlie/tools/ethereum_private_network/ datadir/geth/lightchaindata cache=16 handles=16
INFO [06-19|13:36:54] Writing custom genesis block
INFO [06-19|13:36:54] Successfully wrote genesis state database=lightchaindata hash=ea3061…dd0ee5
- The following folders are created:
~/tools/ethereum_private_network/datadir/geth/chaindata
~/tools/ethereum_private_network/datadir/geth/lightchaindata
The chaindata folder contains the leveldb database files representing the blockchain genesis and
subsequent blocks as they are mined and added to the blockchain. This folder will grow in size over time
and if deleted or lost, the entire blockchain is gone and will need to be re-initialized.
- Modify the ~/tools/ethereum_private_network/Makefile file.
- Make sure the paths are correct.
- Make the NETWORK_ID the same as the chain Id in
~/tools/ethereum_private_network/genesis_private_network.json file.
- Modify the ETHERBASE account. This is the account where mining profits are credited. In this example the account 0xc45ae2b9bfae491c79462aaad05fb4b77e7091f2 is used.
- All loggings are stored in file ~/tools/ethereum_private_network/ethereum.log.
For more information about the geth command line options, type: geth help
- In the Makefile you will see the following lines:
rm -f $(HOME_DIR)/Library/Ethereum/geth.ipc
mkdir -p $(HOME_DIR)/Library/Ethereum
ln -s $(DATA_DIR)/geth.ipc $(HOME_DIR)/Library/Ethereum
These lines does the following:
- If the file $(HOME_DIR)/Library/Ethereum/geth.ipc exists, delete it.
- If the folder $(HOME_DIR)/Library/Ethereum does not exists, create it.
- Create a symbolic link in folder $(HOME_DIR)/Library/Ethereum pointing to $(DATA_DIR)/geth.ipc
Tools such as Ethereum Mist communicates with geth using the geth.ipc file.
This file is created when geth is running.
By default, tools such as Ethereum Mist EXPECT that geth.ipc is located at $(HOME_DIR)/Library/Ethereum/geth.ipc (for macOS).
However my $(DATA_DIR)/geth.ipc is located somewhere else.
By creating a symbolic link i am fixing this problem.
Why am i doing this? Because i have setup different geth nodes on my laptop: one for a private ethereum node,
one for Rinkeby testnet and one for Ropsten testnet.
- Start mining.
Type: cd ~/tools/ethereum_private_network
Type: make mine
You will see:
Welcome to the Geth JavaScript console!
instance: Geth/v1.6.5-stable-cf87713d/darwin-amd64/go1.8.3
coinbase: 0xc45ae2b9bfae491c79462aaad05fb4b77e7091f2
at block: 0 (Thu, 01 Jan 1970 01:00:00 CET)
datadir: /Users/robertlie/tools/ethereum_private_network/--nodiscover
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
>
- You can create another Geth JavaScript console by opening a new terminal and typing the command:
geth attach
Note:
This works if ~/Library/Ethereum/geth.ipc exists (for macOS), if not type:
geth attach /your_path_to/geth.ipc
- The ~/tools/ethereum_private_network/ethereum.log shows the following information:
INFO [06-19|14:43:22] Starting peer-to-peer node instance=Geth/
v1.6.5-stable-cf87713d/darwin-amd64/go1.8.3
INFO [06-19|14:43:22] Allocated cache and file handles database= /Users/robertlie/tools/ethereum_private_network/ datadir/geth/chaindata cache=128 handles=1024
WARN [06-19|14:43:22] Upgrading chain database to use sequential keys
INFO [06-19|14:43:22] Initialised chain configuration config="{ChainID: 987654321 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Metropolis: <nil> Engine: unknown}"
INFO [06-19|14:43:22] Disk storage enabled for ethash caches dir=/Users/robertlie/tools/ ethereum_private_network/datadir/geth/ethash count=3
INFO [06-19|14:43:22] Disk storage enabled for ethash DAGs dir=/Users/robertlie/.ethash count=2
INFO [06-19|14:43:22] Database conversion successful
WARN [06-19|14:43:22] Upgrading db log bloom bins
INFO [06-19|14:43:22] Bloom-bin upgrade completed elapsed=69.382µs
INFO [06-19|14:43:22] Initialising Ethereum protocol versions="[63 62]" network=4321
INFO [06-19|14:43:22] Loaded most recent local header number=0 hash=ea3061…dd0ee5 td=200000000
INFO [06-19|14:43:22] Loaded most recent local full block number=0 hash=ea3061…dd0ee5 td=200000000
INFO [06-19|14:43:22] Loaded most recent local fast block number=0 hash=ea3061…dd0ee5 td=200000000
INFO [06-19|14:43:22] Starting P2P networking
INFO [06-19|14:43:22] RLPx listener up self="enode://30742b167c31c1d5e796cd9499464a33bcd9da272f435b2dc 6fa56a95cc6750b50e633a96b13e7a3323e08011d23e26eeeaac6632073495bc 2c141b55d10558@[::]:30303?discport=0"
INFO [06-19|14:43:22] IPC endpoint opened: /Users/robertlie/tools/ethereum_private_network/datadir/geth.ipc
INFO [06-19|14:43:22] HTTP endpoint opened: http://localhost:8545
INFO [06-19|14:43:22] Starting mining operation
INFO [06-19|14:43:22] Commit new mining work number=1 txs=0 uncles=0 elapsed=125.355µs
INFO [06-19|15:13:06] Successfully sealed new block number=1 hash=6457eb…625a7d
INFO [06-19|15:13:06] 🔨 mined potential block number=1 hash=6457eb…625a7d
INFO [06-19|15:13:06] Commit new mining work number=2 txs=0 uncles=0 elapsed=250.727µs
- You will see the Ethereum's Javascript console prompt. You can enter the following commands:
- eth.accounts
List all accounts
The first account is eth.accounts[0], the second is eth.accounts[1] etc.
- personal.unlockAccount(address, "password")
Unlock accounts (one at a time)
- web3.fromWei(eth.getBalance(eth.coinbase), "ether")
Check the etherbase account balance.
- web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
Show balance of an account.
- personal.newAccount("passwd")
Create a new password protected account.
- personal.unlockAccount(addr, "passwd", duration)
Unlock the account with the given address, password and an optional duration (in seconds).
If password is not given you will be prompted for it.
For example: personal.unlockAccount(eth.coinbase, "passwd", 300);
- txpool.status
Number of pending/queued transactions.
- admin.nodeInfo
Information on the node.
- admin.peers
Show an array of objects with information about connected peers.
More information about the Ethereum's Javascript console and other helpfull commands, see:
https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console
- To stop mining AND close the console, type: exit
If you only want to stop mining, type: miner.stop()
To start mining again, type: miner.start()
|