Building an Ethereum playground with Docker (part 3 — Ethereum Wallet)

I have updated this article on July/2017.

This is the third article in an ongoing series “Building an Ethereum Playground with Docker”. The articles already published are:

The series will cover creating a proper Docker image, playing with Ethereum Wallet, provisioning the ethereum nodes on public clouds and deployment of a sample app.

All sources and scripts are located in https://github.com/vertigobr/ethereum.git.

In this article we will introduce and install the Ethereum Wallet, connect it to our private Ethereum network, create an account and mine into it.

The Wallet

Not just an UI to manage your Ethereum accounts and ether, the Wallet is "…a gateway to decentralized applications on the Ethereum blockchain".

For now we will simply consider the Wallet as a ready-to-use front-end for our playground.

When ran with its default arguments the Wallet also becomes a full Ethereum node connected to the public network (main or testnet, you can choose) — something we don't need in this case. With some (documented) tinkering we will be able to use it to connect to one of our local mining container nodes.

Installing the Wallet

Pick the proper version and download it from Github or from the main Ethereum site. There are installers for many platforms (OSX and Windows, for example) and also a ZIP alternative for manual installation.

Since we will not run the Wallet double-clicking an icon (we wil need to supply command line arguments) please take note of where the Wallet executable file is. This is kinda catchy on OSX but straightforward on the other platforms. The reason is that we will have to run it from the command-line with specific arguments. Let us check this procedure by running the Wallet from a Terminal/Prompt with a "--help" option.

On Windows (use the folder you picked):

D:\Ethereum-Wallet\Ethereum-Wallet.exe --help

On Linux (assuming "/opt" folder):

/opt/Ethereum-Wallet/Ethereum-Wallet --help

On OSX (assuming you placed the app in "Applications"):

/Applications/Ethereum\ Wallet.app/Contents/MacOS/Ethereum\ Wallet --help

The Wallet node

Now we will run a specific node configured for the wallet.

Enabling the JSON-RPC Interface

The default endpoint the Wallet looks for is an local IPC socket with a known path (or a named pipe in Windows). This is hard coded on the Wallet code in a way that becomes somewhat inconvenient to use in our scenario — the "normal" use for the Wallet assumes that it is an ethereum node itself, so an embedded node runs connected to the main net or to the test net (you choose). We need to connect the Wallet to one of our containers instead.

Remember, most of us are running the nodes with Docker for Mac/Windows, so the nodes are inside an "invisible" VM (xhyve or Hyper-V at the time of this writing) and the Wallet app is running in your local OS. Technically your OS is not the Docker host (the "invisible" VM is), so the `geth.ipc` IPC socket file you find in the volume folders is useless for the Wallet.

Instead we will enable another interface in one of our nodes: the JSON-RPC interface, in port 8545. That will work on any of the Wallet versions (OSX, Linux or Windows) — be warned that exposing the JSON-RPC port to the world isn't exactly a good idea, but for now we are working locally in a ephemeral private network that will be discarded anyway. Fear not, little Padawan.

Luckily our helper scripts already provide a way to enable (and expose) the JSON-RPC port easily, by providing an environment variable with the desired port for binding:

./bootnode.sh
# wait for DAG before running wallet
RPC_PORT=8545 ./runminer.sh wallet
Remember that when starting from scratch (after a `./wipeall.sh`) you have to wait for the long "Generating DAG…" process to finish on the first miner. Just check with `docker logs -f ethereum-miner1`. If you run a second miner before it ends both will do the same work. Be patient. Life is beautiful.

The lines above will start a bootnode (as from the last article), a non-exposed mining node and an exposed mining node. The magic behind the script is quite simple: it configures a port binding for the container and runs the node with additional arguments.

The generated port binding is like this, in case you are curious (this is a "docker" argument):

-p $RPC_PORT:8545

And the generated "geth" arguments are these:

--rpc --rpcaddr=0.0.0.0 --rpcapi="db,eth,net,web3,personal" --rpccorsdomain "*"

The JSON-RPC port can be tested from your Terminal easily (you get an JSON response):

> curl -X POST --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}' localhost:8545
{"jsonrpc":"2.0","id":67,"result":"Geth/wallet/v1.6.7-stable/linux-amd64/go1.7.3"}

Oh, no curl in your Windows prompt? You can always use some tool like Postman to send POST requests directly from the browser.

Please note that Docker for Mac/Windows "magic" already takes care of NAT'ing the container exposed ports to "localhost" in your local OS. This is not the default behavior, for example, of "docker-machine" or custom Vagrant VMs, where you most likely work with a host-only IP (ex: "docker-machine ip default"). Just change the hostname for the RPC URL from “localhost” on the next topic to whatever works for you.

Running the Wallet

Now that the JSON-RPC port is exposed in localhost:8545 you can run the Wallet with the proper arguments from the command line.

In OSX:

/Applications/Ethereum\ Wallet.app/Contents/MacOS/Ethereum\ Wallet --rpc http://localhost:8545

This will bring the Wallet UI (ignore the security alert) as seen below:

Wallet on your private network

Notice the "PRIVATE-NET" alert (if it's not there you are doing something wrong). Notice as well that mined blocks count keeps going up — your network is alive and kicking.

Creating an account

This is easy. Click "ADD ACCOUNT" and provide a password you are capable to remember in a few minutes (it gets harder with age, believe me). The UI now looks like this:

OMG, an account id!

Now copy this account id somewhere (the UI has a helper tool anyway) — we will start another mining node in order to mine into this account. Ignore all the warning messages that assume you don't know what you are doing while copying the id on the Wallet UI and finally close the Wallet.

Mining into an account

In order to restart the mining node and to choose the account it mines into just supply an "ETHERBASE" variable to the script with the account id:

ETHERBASE=0x5600...fc050 RPC_PORT=8545 ./runminer.sh wallet

This variable is used in the script to configure the mining container properly.

Reopen the Wallet (run it in the prompt the same way before) and see that it now mines ether into the recently created account.

Actually you don't even have to mine in the same node the account was created, but anywhere in the network (remember: wait for the DAG to end):

ETHERBASE=0x5600...fc050 ./runminer.sh miner1

The node you are connected to with the Wallet will eventually receive the mined blocks from the "miner1" node.

Homework

This can go on and on. Things you can do now just for the fun of it:

Transfer ether between accounts

  • Start another mining node exposing the JSON-RPC on another port (just use another port number in the RPC_PORT variable), and wait for the DAG process to finish;
  • Run another Wallet UI (use this new port on the command-line URL argument);
  • Create another account in this new node;
  • Copy the new account id to the clipboard;
  • Go back to the first Wallet and transfer ether from that account into the new account (you just need the destination account id);
  • Wait a few seconds and the funds will go to the new account!
Ether "wire transfer"

This is really awesome!