Getting started with Ethereum: connecting geth, Remix and Metamask for local development
Tags: blockchain, ethereum, solidity, web3
Published: 2022-01-10 11:47:54

What I thought would have been an easy task turned out to be a **good challenge**.

I'm just getting started with Ethereum and Solidity development, I know that there are frameworks out there that can help you get started faster, but for me, it's also quite important to understand what is going on behind the scenes before moving to a framework that abstracts those things away.

My goal was:

1. run an Ethereum node **locally**
2. connect a wallet to my **local node**, so I can see what's going on
3. deploy a "test" smart contract

In the end, I chose `geth` as the Ethereum node, `Metamask` as the wallet and `Remix` as the tool to help me deploy a smart contract.

_I'm not going to enter the merit about I chose those tools above, they just seem reasonably good at first glance, and most of them are often mentioned in tutorials out there_

The challenge here was to connect those things together. Since there's no framework behind it, you have to figure out some things on your own.

The first step is to run `geth` with the appropriate configuration for development.

## Geth

You can run `geth` in development mode by following the steps mentioned [here](https://geth.ethereum.org/docs/getting-started/dev-mode) however, it's not clear how to connect to other tools like `Metamask`.

I ended up running `geth` with the following options:

* `--datadir`: location for the database and keystores, avoids losing the state when restarting `geth`
* `--dev`: changes geth to "local" mode, it does not connect to external nodes and also bootstraps an account with `eth`
* `--http`: enables HTTP server
* `--http.api web3,eth,debug,personal,net`: enables the following APIs via HTTP - safe for development only
* `--ws`: enables websockets server
* `--ws.api web3,eth,debug,personal,net`: enables the following APIs via websockets - again, safe only for development
* `--vmdebug`: enable debugging
* `--http.corsdomain`: enable requests to the `geth` process via HTTP only for some specific domains.

The full command will depend on the URL of the Metamask in your browser.

## Getting the Metamask URL

Metamask is not obligatory to develop locally, but if you're getting started (like me), it helps you understand some basic concepts.

To connect Metamask to your local `geth`, you need to add the URL of the browser extension. To get the URL:

* Open the Metamask extension (this will show a popup in the browser)
* Click on the three dots next to your account and "expand view", this will open a new tab/window.
* Copy the URL of the new window. If you're using Firefox, it may look like this: `moz-extension://aaac9e04-2a0d-45a8-bb45-7ad026ae5536`

## The full command

I prefer to start geth node together with the `console` on, to do that, run:

    geth --datadir geth-test-chain-dir \
         --dev \
         --http \
         --http.corsdomain "https://remix.ethereum.org,moz-extension://aaac9e04-2a0d-45a8-bb45-7ad026ae5536" 
         --http.api web3,eth,debug,personal,net \
         --ws \
         --ws.api web3,eth,debug,personal,net \
         --vmdebug \
         console

To check if everything is running correctly, you can run on the console:

    > eth.accounts
    ["0xaaa..."]

## Connecting Metamask

To connect your local `geth` to Metamask, you need to change it to use the "test networks". 

Click on the dropdown next to your account icon and choose "Localhost 8545". If you don't see it, you need to change the settings to display "test networks".

Note: sometimes it takes a while to connect. Usually after a refresh of the Metamask extension page a few times it works, but sometimes closing and opening the browser helps.

## Test transaction

If you started `geth` in dev mode together with `console`, you can run:

    > personal.newAccount()

This will prompt for a passphrase, remember that.

After that, you can transfer some eth:

    > eth.accounts[1]
    "0xaaa..."
    > eth.sendTransaction({from: eth.coinbase, to: eth.accounts[1], value: web3.toWei(1, "ether")})

This will send `1 ETH` from the default account created by development mode to the newly created account (you can also use the string address instead of the array position).

You can now import this account into Metamask. 

* Click on the account icon and choose "Import Account". 
* Choose the JSON type for import and upload the file from your `geth-test-chain-dir/keystore/...aaa...`
* Put the passphrase you typed in the prompt before

You now should see the account you just created with `1 ETH`. If something is not working correctly:

* make sure you're connected to `Localhost node`
* make sure you're importing the proper JSON file, there might be two or more files
* make sure you're using the correct passphrase

That's it, good luck!

## References:

* Installing geth: https://geth.ethereum.org/docs/install-and-build/installing-geth
* Running geth on dev mode: https://geth.ethereum.org/docs/getting-started/dev-mode
* Remix IDE: https://remix.ethereum.org
* Running Remix: https://remix-ide.readthedocs.io/en/latest/run.html
* Using Metamask with a local node: https://metamask.zendesk.com/hc/en-us/articles/360015290012-Using-a-Local-Node