How to set up a private Ethereum testnet blockchain using Geth and Homebrew

Lander Willems
Aug 5, 2017 · 8 min read

An entry tutorial for kicking off your Solidity programming ambitions!

Image from

About me

Hi! My name is Lander. I’m a freelance software engineer and product builder from Belgium. When I’m not dabbling in Solidity, I’m working on TeamHut, a SaaS to help freelancers and digital teams organise & share their digital content.

About this tutorial

This tutorial is an interpretation of different resources that helped me get up & running setting up my first private Ethereum testnet blockchain using Geth and Homebrew. It serves as a future reference for myself and as a help for other crypto enthusiasts. I tried to list most of my resources at the bottom of this article. Please let me know if you feel anything’s missing.

Private Ethereum testnet blockchain

Ethereum software enables a user to set up a “private” or “testnet” Ethereum chain that is separate from the main Ethereum chain. This is useful for testing distributed apps built on Ethereum without having to expose your apps to the real Ethereum network using real Ether. You either pre-generate or mine your own Ether on your private Ethereum chain, so it is a much more cost effective way of trying out Ethereum. Have I said Ethereum enough?

Let’s Geth crackin’

What do you need for this tutorial?

A few assumptions

  • You are using MacOS
  • You are a crypto and/or software development enthusiast who’s wanting to make his/her first steps into writing smart contracts.
  • You know what Ethereum is and understand it’s basic usage.
  • You have a basic understanding of MacOS Terminal usage.

What will you achieve?

After successfully completing this tutorial, you’ll have a fully functional private Ethereum testnet blockchain running on your local computer.

This private testnet will allow you to develop and test your current Dapps (Decentralized Apps) in isolation from the real Ethereum blockchain.


What is Homebrew?

Homebrew installs the stuff you need that Apple didn’t. I’m not kidding, that’s what their website says. Go & check it out, it’s awesome.

What is Ethereum?

Ethereum is a cutting edge blockchain-based distributed computing platform, featuring smart contract functionality. It provides a decentralized virtual machine, the Ethereum Virtual Machine (EVM), that can execute peer-to-peer contracts using a crypto-fuel called Ether.

Read the white paper here.

What is Geth?

geth is the the command line interface for running a full ethereum node implemented in Go. It is the main deliverable of the Frontier Release.

By installing and running geth, you can take part in the ethereum live network, mine ether on the blockchain, transfer funds between addresses, create contracts and send transactions.

Before you use geth or interact with the ethereum Frontier live network, make sure you read the documentation and fully understand the caveats and risks.


How to install Homebrew

If you haven’t done so yet, fire up your Terminal and start off by installing Homebrew:

/usr/bin/ruby -e "$(curl -fsSL"

If you’ve already installed Homebrew previously, make sure it’s up to date:

brew update
brew upgrade

How to install Geth

The easiest way to install Geth (go-ethereum) is to use the Homebrew tap

brew tap ethereum/ethereum 
brew install ethereum

Test if the installation was successful by running

geth version

This should display your currently installed Geth version:

Version: 1.6.7-stable
Git Commit: ab5646c532292b51e319f290afccf6a44f874372
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.8.3
Operating System: darwin

As you can see, we’re currently running Geth version 1.6.7.
Make sure to check the different options and commands with geth --help as well!

Let’s get dangerous

Lets’s Get Dangerous —

Connecting to the test net

Let’s start by creating a genesis block for your private testnet blockchain. The genesis block is the start of the blockchain — the first block, block 0, and the only block that does not point to a predecessor block. The protocol ensures that no other node will agree with your version of the blockchain unless they have the same genesis block, so you can make as many private testnet blockchains as you’d like! (See documentation)

Create & save a *.json file called CustomGenesis.json and put these contents in it:

As mentioned in this blog post, there’s a Python tool available to generate your own custom Genesis file. For simplicity’s sake, you can just copy paste this example:

"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
"difficulty": "0x400",
"gasLimit": "0x2100000",
"alloc": {
{ "balance": "0x1337000000000000000000" }

The file acts as a ‘seed’ for your private testnet.

We’ve lowered the difficulty down to 400, so mining new blocks goes faster.

Notice that we added our account address 93f932b3b87e08cdaf0877994e44feb4c93e81aa to the "alloc" object, and that we gave it a balance of 1337000000000000000000 wei (1337 ETH):

"alloc": {
{ "balance": "0x1337000000000000000000" }

You can use this technique to pre-fund your account. You can define multiple accounts to include in the seed. Note that this step is optional, as you can easily mine the Ether yourself, as you’re in control of the (low) difficulty!

You will reference this file (CustomGenesis.json) when initialising your genesis block using the following command:

geth --identity "MyTestNetNode" --nodiscover --networkid 1999 --datadir /path/to/test-net-blockchain  init /path/to/CustomGenesis.json

Pro Tip
I’m using a custom `datadir` flag to separate the testnet blockchain from the real one. I suggest you do as well. This can be any folder you want.

To learn more about the other flags used, please navigate to the documentation.

Creating an account on the private tesnet

Create or find a directory where you’d like to store your local private testnet data. For this example, we’ll be using


After the previous geth --version command ran successfully, run

geth account new --datadir /path/to/test-net-blockchain

This command will ask you for a passphrase (=password). Do not forget this.

Pro Tip
I’m using a custom `datadir` flag to indicate that I’d like to use my personal, local testnet. This keeps it separated from the real testnet.

By default geth will use the same directory for network related files as for the public mainnet. Thus you are advised to set a custom --datadir to keep the public network’s chaindata from being reset.

To learn more about this, see documentation.

This will create an account on your fresh testnet node, and will return the private testnet address like so:

Address: {93f932b3b87e08cdaf0877994e44feb4c93e81aa}

Save this address and your password for later use.

Pre funding your account

This is an optional step. As the difficulty is so low, it would only take you a few minutes to mine enough Ether to get you going.

Start by removing your previously created blockchain database:

geth removedb --datadir /path/to/test-net-blockchain

Update your ‘CustomGenesis.json’ file:

"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
"difficulty": "0x400",
"gasLimit": "0x2100000",
"alloc": {
{ "balance": "0x1337000000000000000000" }


Notice that we added our account address 93f932b3b87e08cdaf0877994e44feb4c93e81aa to the "alloc" object, and that we gave it a balance of 1337000000000000000000 wei (1337 ETH):

You can define multiple accounts to include in the seed.

Run the Genesis block initialisation command again

geth --identity "MyTestNetNode" --nodiscover --networkid 1999 --datadir /path/to/test-net-blockchain  init /path/to/CustomGenesis.json

If you haven’t done the prefunding

Use this command after starting the JavaScript Console (see next step: ‘Interact with Geth console’):

geth --identity "MyTestNetNode" --datadir /path/to/test-net-blockchain --nodiscover --networkid 1999 console

Interact with Geth console

To interact with Geth through the console, called the Geth JavaScript Console use:

geth --identity "MyTestNetNode" --datadir /path/to/test-net-blockchain --nodiscover --networkid 1999 console

If it ran successfully, you should see a confirmation:

If you see this message you can start running Geth JavaScript commands.
Try to use this one to check the balance of your primary account

web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")

Pro Tip
Store these long Geth commands in separate *.sh files so you can re use the configuration (and it’s custom flags) at a later time. You’ll need this every time you’ll want to use your (custom) private testnet.

Folder Structure

Purely informational, this is what my folder structure looks like:

My folder structure

As you can see, I created some *.sh script to re-use later on.

I’ve created a repository containing the ones I used as a reference for this article:

Image from


You now have a functioning private Ethereum testnet blockchain and an account/wallet running on your personal computer. You can now start mining, send transactions, etc. I’ll be writing some new articles regarding these topics in the near future.

Useful commands/tips

  1. geth removedb
    Deletes/removes your locally synced blockchain data of the public testnet.
  2. geth removedb --datadir /path/to/test-net-blockchain
    Deletes/removes your private blockchain testnet data.
  3. geth --fast --cache=1024
    Synchronises the blockchain more quickly. If you choose to use the — fast flag to perform an Ethereum fast sync, you will not retain past transaction data.
  4. When using geth attach when running a private testnet,
    be sure to include the IPC endpoint.
    The IPC endpoint is shown when starting your Geth JavaScript console
    as such:IPC endpoint opened: /path/to/endpoint/geth.ipc
    Attach the path to your command so it becomes:
    geth attach /path/to/endpoint/geth.ipc

Geth JavaScript console commands

Use these commands once your logged into the Geth console.

  1. If you receive an error saying ‘Error: authentication needed: password or unlock’, use this command to unlock your primary account in the Geth JavaScript console:
    personal.unlockAccount(eth.coinbase, 'your account password in quotes', 0)
  2. To check the balance of your primary account
web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")

3. To see a list of pending transactions


Useful links

Thanks for reading!

I’d love to hear from you and know what you think. Please let me know if you think anything’s missing. If you’d like to keep in touch, respond to this post below, follow me on Twitter or sign up to my newsletter using the form below.


Coinmonks is a non-profit Crypto educational publication.

Lander Willems

Written by

Freelance Software Engineer



Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project —

More From Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade