So you want to be an Ethereum developer! Congrats, much treasure awaits you. Developing Ethereum dapps benefits from having a well-crafted development environment. This can often be daunting to beginners, so I'm giving you my favorite dev environment to help get you started.
Once your code fortress is constructed, you'll be able to
- Compile smart contracts written in Solidity
- Run Ethereum nodes on both the mainnet and Rinkeby testnet
- Deploy contracts to either mainnet or testnet
- Interact with said contracts
This gist complements other Ethereum gists:
- How to get on Rinkeby Testnet in less than 10 minutes
- How to Create and Participate in a Crowdfunding Contract
The easiest way is to set up an node on Google Cloud Platform (GCP) or Amazon Web Services (AWS). For this tutorial, we'll concentrate on GCP, because I already used up all my free AWS credits :) If you want the AWS version, send some free credits to paul at invisible dot college.
We'll be using some pre-built Docker images to save you some work, geth
which is the official
Ethereum reference implementation written in Go, and democracy
which is a Javascript Ethereum framework
being developed at the Invisible College.
Go to https://console.cloud.google.com/freetrial and sign in with a Google account that hasn't used a free trial before.
Congrats! You'll get $300 of credits to use over the next year. Don't worry, you'll only use these up very slowly running an Ethereum node.
Once your account is established, go to the left sidebar and choose
Compute -> Compute Engine -> VM Instances
.
Click on "Create VM Instance". Most of the defaults are okay here.
I use the Ubuntu 16.04 LTS (Xenial) image, but you'll be fine with any other recent Ubuntu or Debian distro. For example, the latest at the time of this writing are Ubuntu 17.04 (Zesty) and Debian 9 (stretch), both of which are great.
Click "Create".
Your geth nodes will need to be able to listen on TCP and UDP ports 30303 to synchronize the blockchain.
The other port geth nodes commonly listen on is 8545 if you want to let outside hosts access your node via JSON-RPC, but this isn't recommended by default.
Some big-hearted companies like Augur run a public node and let people hit them from the outside, e.g. for web pages that need read-only access to the Ethereum blockchain. However, these nodes don't have private keys attached to them, so you can't use them to deploy contracts.
We'll only be hitting the JSON-RPC port locally with Democracy, although you can
also curl
directly to port 8545 using the web3 JSON-RPC protocol.
In the olden days before Democracy, I would have to painstakingly build a dev environment from scratch, installing geth and a dozen other apt packages, downloading and configuring NodeJS and npm packages. It was enough to make one go back to fiat currencies, but not quite that bad.
Now you can pull and run a pre-built Docker image that does all of that for you. A short-coming of Docker is that you can't currently distribute an easy run configuration with your image. So you still have to manually send them the right commands to publish the right exposed ports and mount the right volumes.
We'll start with running a Rinkeby testnet node.
It often helps in Ethereum development, and many other coding tasks, to have several terminal windows open.
I prefer tmux
, a terminal multiplexer, which is a flexible and powerful way to separate your screen
into multiple independent panes and keep alive long-running jobs even if you get disconnected.
If it's not already installed on your GCP node, you can get it with
apt install tmux
and then run it with
tmux
To start with, you'll see a single pane with a green bottom border to let you know you're inside tmux. You're living the tmux dream!
As a short primer, you can split your screen into two vertical panes with the keystrokes Ctrl-b
%
and into two horizontal panes with the keystrokes Ctrl-b
"
.
You can move between the panes by pressing Ctrl-b
and arrow keys to move the focus to another pane in that direction.
In case you didn't guess, all tmux commands begin with the keystrokes Ctrl-b
:)
You can get more help with Ctrl-b
?
, or you can refer to one of many great cheatsheets online.
These instructions accomplish the same steps as How to get on Rinkeby Testnet in less than 10 minutes but faster. You should still follow the end of those instructions to get Rinkeby ether from a faucet.
Here's the command to pull and run the Docker image, publish the right exposed ports so you can listen for incoming connections through the GCP firewall, and commune with other Ethereum nodes in the void.
ppham@ethereum-prime:~/src/democracy/docker$ docker run -p 30303:30303 -p 8545:8545 cryptogoth/geth-rinkeby
Soon you'll get output like the
+ NETWORK_ID=4
+ GETH='geth --datadir=/root/.rinkeby --networkid 4'
+ BOOTNODES=--bootnodes=enode://a24ac7c5484ef4ed0c5eb2d36620ba4e4aa13b8c84684e1b4aab0cebea2ae45cb4d375b77eab56516d34bfbd3c1a833fc51296ff084b770b94fb9028c4d25ccf@52.169.42.101:30303
++ echo /root/.nodeidentity
+ RPC='--rpc --rpccorsdomain '\''*'\'' --identity /root/.nodeidentity --password /root/.accountpassword --extradata '\''cryptogoth'\'''
+ '[' '!' -z '' ']'
+ geth --datadir=/root/.rinkeby --networkid 4 --cache=512 '--ethstats=yournode:Respect my [email protected]' --bootnodes=enode://a24ac7c5484ef4ed0c5eb2d36620ba4e4aa13b8c84684e1b4aab0cebea2ae45$
b4d375b77eab56516d34bfbd3c1a833fc51296ff084b770b94fb9028c4d25ccf@52.169.42.101:30303 --rpc --rpccorsdomain ''\''*'\''' --identity /root/.nodeidentity --password /root/.accountpassword --extradata ''\''cr$
ptogoth'\'''
INFO [07-30|23:43:21] Starting peer-to-peer node instance=Geth//root/.nodeidentity/v1.6.7-stable-ab5646c5/linux-amd64/go1.8.1
INFO [07-30|23:43:21] Allocated cache and file handles database=/root/.rinkeby/geth/chaindata cache=512 handles=1024
WARN [07-30|23:43:21] Upgrading chain database to use sequential keys
INFO [07-30|23:43:21] Initialised chain configuration config="{ChainID: 4 Homestead: 1 DAO: <nil> DAOSupport: false EIP150: 2 EIP155: 3 EIP158: 3 Metropolis: <nil> Engine: clique}"
WARN [07-30|23:43:21] Upgrading db log bloom bins
INFO [07-30|23:43:21] Bloom-bin upgrade completed elapsed=1.421ms
INFO [07-30|23:43:21] Initialising Ethereum protocol versions="[63 62]" network=4
INFO [07-30|23:43:21] Database conversion successful
INFO [07-30|23:43:21] Loaded most recent local header number=0 hash=6341fd…67e177 td=1
INFO [07-30|23:43:21] Loaded most recent local full block number=0 hash=6341fd…67e177 td=1
INFO [07-30|23:43:21] Loaded most recent local fast block number=0 hash=6341fd…67e177 td=1
INFO [07-30|23:43:21] Starting P2P networking
INFO [07-30|23:43:23] UDP listener up self=enode://15c5f3750bbf64b457f00122b9890f560ca81c9a4f14e85d7c55a6a9e24c8e96e3dc125c4564df689585275c54f298190b22c0f6e3ae846b95439603cdc922c3
@[::]:30303
INFO [07-30|23:43:23] Stats daemon started
INFO [07-30|23:43:23] HTTP endpoint opened: http://127.0.0.1:8545
INFO [07-30|23:43:23] RLPx listener up self=enode://15c5f3750bbf64b457f00122b9890f560ca81c9a4f14e85d7c55a6a9e24c8e96e3dc125c4564df689585275c54f298190b22c0f6e3ae846b95439603cdc922c3
@[::]:30303
The following lines let you know you're actually synchronizing with other Ethereum nodes.
INFO [07-30|23:43:33] Block synchronisation started
INFO [07-30|23:43:33] Imported new state entries count=1 flushed=0 elapsed=222.212µs processed=1 pending=17 retry=0 duplicate=0 unexpected=0
INFO [07-30|23:43:34] Imported new state entries count=16 flushed=0 elapsed=1.357ms processed=17 pending=273 retry=0 duplicate=0 unexpected=0
INFO [07-30|23:43:34] Imported new state entries count=107 flushed=0 elapsed=9.718ms processed=124 pending=1985 retry=0 duplicate=0 unexpected=0
INFO [07-30|23:43:34] Imported new block headers count=192 elapsed=71.591ms number=192 hash=8c570c…ba360c ignored=0
INFO [07-30|23:43:34] Imported new block receipts count=54 elapsed=3.555ms number=54 hash=dafe6e…02bf13 ignored=0
The part that says Imported new block headers
and number=192
means that you've downloaded headers for up to block 192.
To see the latest block in the Ethereum Rinkeby blockchain, you go to (http://rinkeby.etherscan.io).
At the time of this writing, it's 629860.
You'll need to wait about 9 minutes to do this. Which is still great, considering that it used to take me 6 hours and 50 GB to sync geth overnight.
In a separate tmux
pane, create a symlink