Part 14: Ethereum Node Setup
In this part we will edit our docker stack to run more service, the Ethereum node. It's required for our application to be able to connect to the Ethereum network to execute and query cryptocurrency transactions.
Hi. Good morning guys.
This is your one stop channel to become a full stack blockchain engineer.
This is part 14 of the whole course on how to build a Crypto E-Wallet and Exchange System using Odoo.
In this part we will edit our docker compose file to run more service, which is the Ethereum node.
Before continuing, please consider to like, share, and subscribe our channel if you find it useful, as we will update the topics of Building E-wallet Exchange system with Odoo regularly.
Ok, now let's talk about the Ethereum Node setup and configuration in details.
---
What is Ethereum Node
An Ethereum node is simply a computer that is running the Ethereum software and is connected to the Ethereum network. It is responsible for validating and relaying transactions and blocks, and for maintaining a copy of the Ethereum blockchain.
[ethereum node -- ethereum network]
Types of Ethereum Node
There are two main types of Ethereum nodes: full nodes and light nodes.
Full nodes download and validate the entire Ethereum blockchain, which is currently over 500GB in size. This allows them to fully verify the authenticity and integrity of all transactions and blocks on the network. Full nodes are typically used by miners, exchanges (like our application), and other organizations that need to ensure the highest level of security and performance.
Light nodes, on the other hand, do not download the entire blockchain and instead rely on other full nodes for data. They only store a small portion of the blockchain data in memory (called a "cache") and retrieve the rest on demand. This makes them much faster to set up and run, but also less secure and less capable of fully verifying transactions and blocks.
Light nodes are typically used by users who want to interact with the Ethereum network but do not need to run a full node for security or performance reasons.
[full node vs light node]
Software Package to Run Ethereum Node
Ethereum nodes communicate with each other using a peer-to-peer protocol and help to keep the Ethereum network decentralized by participating in the consensus process.
You can run your own Ethereum node by installing the Ethereum software (such as Geth or Parity) on your computer and connecting it to the Ethereum network.
Geth website:
Parity website:
Unfortunately, Parity, which turn out to be OpenEthereum, is now archived by the owner, so we will be using Geth in this tutorial.
You can also use a cloud-based node service or a third-party provider to access the Ethereum network without running your own node. This includes:
-
Moralis (moralis.io)
-
Chainstack (chainstack.com)
-
Quicknode (quicknode.com)
-
etc
Why Do We Need Ethereum Node
There are several reasons why running an Ethereum node can be useful:
Decentralization: Ethereum is a decentralized platform that relies on a network of nodes to validate and relay transactions and blocks. By running an Ethereum node, we can help to support the network and contribute to its decentralization.
Security: Full nodes validate the entire Ethereum blockchain, which helps to ensure the authenticity and integrity of all transactions and blocks on the network. This can be especially important for users who need to ensure the highest level of security, such as miners, our exchange application, and other organizations.
Access to the Ethereum network: To interact with the Ethereum network and participate in smart contracts, we will need to connect to an Ethereum node. By running our own node, we can have more control over your connection to the network and potentially improve the performance of our transactions.
Development: We are developing an exchange application on top of Ethereum, so we need the node for testing and debugging our application.
[running our own node]
Ethereum Node Sync Modes
In Geth, the Ethereum client software, there are several sync modes that you can use to synchronize the Ethereum blockchain:
Full sync mode: This mode downloads and verifies every block and transaction since the beginning of the blockchain. This is the most secure and accurate way to sync the blockchain, but it can be slow and require a large amount of disk space, let's talk about 2TB to start.
Fast sync mode: This mode is designed to quickly catch up with the current state of the blockchain by downloading and verifying only the block headers and state trie data. It then downloads and verifies the full blocks in the background. This mode is faster than the full sync mode, but it still requires a significant amount of disk space to store the blockchain data.
Light sync mode: This mode is designed to be more lightweight and efficient. It does not download the entire blockchain and instead relies on other full nodes for data. It only stores a small portion of the blockchain data in memory (called a "cache") and retrieves the rest on demand. This makes it much faster to set up and run, but also less secure and less capable of fully verifying transactions and blocks.
For our development stage, we can use the light mode to save time and resources.
But, once we are on production stage, the full node setup is mandatory for security and performance reason.
Can we Use Third Party Nodes?
It's worth noting that running an Ethereum node is not necessary for all users, and there are other ways to access the Ethereum network without running our own node.
For example, you can use a cloud-based node service or a third-party provider to interact with the network without the need to run your own node.
Some examples are:
-
Moralis
-
Chainstack
-
Quicknode
-
etc.
For the production level, we will need our own node, for security and performance reason, but for development purpose, you can still use one of the third party providers. We will talk about using those services in other videos later, but simply just obtain the JSON-RPC address and port to gain access to the network via those providers.
Setup Ethereum Node Docker Stack
Open your docker-compose.yml file we created before on the previous part.
We will add more services on the docker stack, which, in this case, is the geth software.
version: '3.7'
services:
odoo:
...
db:
...
geth:
image: ethereum/client-go:stable
command:
- --goerli
- --syncmode=light
- --http
- --http.api=eth,net,web3,engine,admin,personal
- --http.addr=0.0.0.0
- --http.vhosts=*
- --http.corsdomain=*
- --ws
- --ws.origins=*
- --ws.addr=0.0.0.0
- --ws.api=eth,net,web3
- --graphql
- --graphql.corsdomain=*
- --graphql.vhosts=*
- --authrpc.addr=0.0.0.0
- --authrpc.vhosts=*
- --authrpc.jwtsecret=/root/.ethereum/jwt.hex
- --authrpc.port=8551
- --txlookuplimit=0
ports:
- "8545:8545"
volumes:
- ./chaindata:/root/.ethereum
We create an additional service called "geth" that runs the Ethereum client, Geth, in light sync mode with a cache size of 1024MB.
It will connect to the Kovan test network, as we are in development stage, defined by the
"--testnet" option.
Once we are ready to deploy our application on the main net, then just remove the
"--testnet" option, and change the "--syncmode" option to full.
It exposes the JSON-RPC server on port 8545.
It mounts the ./chaindata directory on our local host as a volume to persist the blockchain data.
Run the Node
As always, we can then use
docker-compose up
command to start the Geth container and
docker-compose down
to stop it.
You will see something like this:
geth_1 | INFO [12-28|05:54:57.502] Starting Geth on Görli testnet...geth_1 | INFO [12-28|05:54:57.502] Dropping default light client cache provided=1024 updated=128
geth_1 | INFO [12-28|05:54:57.507] Maximum peer count ETH=0 LES=10 total=50
geth_1 | INFO [12-28|05:54:57.526] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
geth_1 | INFO [12-28|05:54:57.579] Set global gas cap cap=50,000,000
geth_1 | INFO [12-28|05:54:57.583] Allocated cache and file handles database=/root/.ethereum/goerli/geth/lightchaindata cache=64.00MiB handles=524,288
geth_1 | INFO [12-28|05:55:02.228] Allocated cache and file handles database=/root/.ethereum/goerli/geth/les.client cache=16.00MiB handles=16
geth_1 | INFO [12-28|05:55:02.674]
geth_1 | INFO [12-28|05:55:02.674] ---------------------------------------------------------------------------------------------------------------------------------------------------------
geth_1 | INFO [12-28|05:55:02.674] Chain ID: 5 (goerli)
geth_1 | INFO [12-28|05:55:02.674] Consensus: Beacon (proof-of-stake), merged from Clique (proof-of-authority)
geth_1 | INFO [12-28|05:55:02.674]
geth_1 | INFO [12-28|05:55:02.674] Pre-Merge hard forks:
geth_1 | INFO [12-28|05:55:02.674] - Homestead: 0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)
geth_1 | INFO [12-28|05:55:02.674] - Tangerine Whistle (EIP 150): 0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/tangerine-whistle.md)
geth_1 | INFO [12-28|05:55:02.674] - Spurious Dragon/1 (EIP 155): 0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)
geth_1 | INFO [12-28|05:55:02.674] - Spurious Dragon/2 (EIP 158): 0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)
geth_1 | INFO [12-28|05:55:02.674] - Byzantium: 0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)
geth_1 | INFO [12-28|05:55:02.674] - Constantinople: 0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)
geth_1 | INFO [12-28|05:55:02.674] - Petersburg: 0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)
geth_1 | INFO [12-28|05:55:02.674] - Istanbul: 1561651 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)
geth_1 | INFO [12-28|05:55:02.674] - Berlin: 4460644 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md)
geth_1 | INFO [12-28|05:55:02.674] - London: 5062605 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md)
geth_1 | INFO [12-28|05:55:02.674]
geth_1 | INFO [12-28|05:55:02.674] Merge configured:
geth_1 | INFO [12-28|05:55:02.674] - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md
geth_1 | INFO [12-28|05:55:02.674] - Network known to be merged: true
geth_1 | INFO [12-28|05:55:02.674] - Total terminal difficulty: 10790000
geth_1 | INFO [12-28|05:55:02.675] - Merge netsplit block: <nil>
geth_1 | INFO [12-28|05:55:02.675] ---------------------------------------------------------------------------------------------------------------------------------------------------------
geth_1 | INFO [12-28|05:55:02.675]
geth_1 | INFO [12-28|05:55:02.736] Added trusted checkpoint block=6,914,047 hash=bb11ea..76db2f
geth_1 | INFO [12-28|05:55:02.740] Loaded most recent local header number=7,317,792 hash=17bd0e..ec1248 td=10,695,920 age=5mo12h53m
geth_1 | INFO [12-28|05:55:02.761] Configured checkpoint oracle address=0x18CA0E045F0D772a851BC7e48357Bcaab0a0795D signers=5 threshold=2
geth_1 | INFO [12-28|05:55:02.761] Gasprice oracle is ignoring threshold set threshold=2
geth_1 | INFO [12-28|05:55:02.761] Upgrading chain index type=cht percentage=95
geth_1 | WARN [12-28|05:55:02.765] Unclean shutdown detected booted=2022-12-28T05:45:09+0000 age=9m53s
geth_1 | WARN [12-28|05:55:02.765] Catalyst mode enabled protocol=les
geth_1 | INFO [12-28|05:55:02.772] Starting peer-to-peer node instance=Geth/v1.10.26-stable-e5eb32ac/linux-amd64/go1.18.8
geth_1 | INFO [12-28|05:55:03.234] New local node record seq=1,672,206,009,452 id=631558cd1dc81eee ip=127.0.0.1 udp=30303 tcp=30303
geth_1 | INFO [12-28|05:55:03.242] Started P2P networking self=enode://6be66bac4d9c924a8639a0155ca97e2718d81e824adfd29f944b583d5d4c088f99dd71b07108ae811ed422277799ea15853c1d306db1e1c07f85d30e80818ed3@127.0.0.1:30303
geth_1 | INFO [12-28|05:55:03.255] IPC endpoint opened url=/root/.ethereum/goerli/geth.ipc
geth_1 | INFO [12-28|05:55:03.271] Loaded JWT secret file path=/root/.ethereum/jwt.hex crc32=0xf66100f4
geth_1 | INFO [12-28|05:55:03.272] HTTP server started endpoint=[::]:8545 auth=false prefix= cors=* vhosts=*
geth_1 | INFO [12-28|05:55:03.272] GraphQL enabled url=http://[::]:8545/graphql
geth_1 | INFO [12-28|05:55:03.272] GraphQL UI enabled url=http://[::]:8545/graphql/ui
geth_1 | INFO [12-28|05:55:03.273] WebSocket enabled url=ws://[::]:8546
geth_1 | INFO [12-28|05:55:03.273] WebSocket enabled url=ws://[::]:8551
geth_1 | INFO [12-28|05:55:03.273] HTTP server started endpoint=[::]:8551 auth=true prefix= cors=localhost vhosts=*
geth_1 | WARN [12-28|05:55:03.273] Light client mode is an experimental feature
geth_1 | INFO [12-28|05:55:04.420] Block synchronisation started
After a while our geth will start synchronizing the the network, and we can see the logs as follows..
geth_1 | INFO [12-28|05:55:32.879] Imported new block headers count=192 elapsed=145.182ms number=7,318,176 hash=9b3fb8..fa0e68 age=5mo11h17m geth_1 | INFO [12-28|05:55:33.941] Imported new block headers count=192 elapsed=148.388ms number=7,318,368 hash=896c2e..039d69 age=5mo10h29m geth_1 | INFO [12-28|05:55:36.114] Imported new block headers count=1344 elapsed=2.161s number=7,319,712 hash=c58ed2..29c771 age=5mo4h51m geth_1 | INFO [12-28|05:55:37.764] Imported new block headers count=1920 elapsed=1.649s number=7,321,632 hash=60b4a3..95f886 age=4mo4w1d geth_1 | INFO [12-28|05:55:39.440] Imported new block headers count=2048 elapsed=1.676s number=7,323,680 hash=5995aa..4b70e9 age=4mo4w1d geth_1 | INFO [12-28|05:55:41.671] Imported new block headers count=2048 elapsed=2.230s number=7,325,728 hash=dea504..cec693 age=4mo4w1 geth_1 | INFO [12-28|05:55:43.478] Imported new block headers count=2048 elapsed=1.807s number=7,327,776 hash=1dc06f..78880e age=4mo4w19h geth_1 | INFO [12-28|05:55:45.361] Imported new block headers count=2048 elapsed=1.879s number=7,329,824 hash=ca4544..532484 age=4mo4w10h geth_1 | INFO [12-28|05:55:47.324] Imported new block headers count=2048 elapsed=1.962s number=7,331,872 hash=b7abd7..9db4be age=4mo4w1h geth_1 | INFO [12-28|05:55:49.173] Imported new block headers count=2048 elapsed=1.848s number=7,333,920 hash=6450c2..a1864b age=4mo3w6d geth_1 | INFO [12-28|05:55:50.680] Imported new block headers count=2048 elapsed=1.506s number=7,335,968 hash=ec1ba8..512730 age=4mo3w6d geth_1 | WARN [12-28|05:55:53.261] Database compacting, degraded performance database=/root/.ethereum/goerli/geth/lightchaindata geth_1 | INFO [12-28|05:56:48.183] New local node record seq=1,672,206,009,453 id=631558cd1dc81eee ip=140.0.200.251 udp=60139 tcp=30303 geth_1 | WARN [12-28|05:56:53.217] Database compacting, degraded performance database=/root/.ethereum/goerli/geth/lightchaindata geth_1 | WARN [12-28|05:57:53.162] Database compacting, degraded performance database=/root/.ethereum/goerli/geth/lightchaindata geth_1 | WARN [12-28|05:58:53.163] Database compacting, degraded performance database=/root/.ethereum/goerli/geth/lightchaindata geth_1 | INFO [12-28|05:59:01.405] Imported new block headers count=1216 elapsed=3m10.955s number=7,337,184 hash=f257f2..473fd2 age=4mo3w6d geth_1 | INFO [12-28|05:59:03.317] Imported new block headers count=2048 elapsed=1.912s number=7,339,232 hash=d17d35..d39e11 age=4mo3w5d geth_1 | INFO [12-28|05:59:05.610] Imported new block headers count=2048 elapsed=2.292s number=7,341,280 hash=7023d9..1a1816 age=4mo3w5d geth_1 | INFO [12-28|05:59:06.667] Imported new block headers count=1088 elapsed=1.057s number=7,342,368 hash=8eb916..83ec50 age=4mo3w5d geth_1 | INFO [12-28|05:59:09.239] Imported new block headers count=2048 elapsed=2.571s number=7,344,416 hash=05a476..79df8c age=4mo3w4d geth_1 | INFO [12-28|05:59:11.277] Imported new block headers count=2048 elapsed=2.034s number=7,346,464 hash=75399e..7ace04 age=4mo3w4d geth_1 | INFO [12-28|05:59:11.649] Upgrading chain index type=bloomtrie percentage=96 geth_1 | INFO [12-28|05:59:12.813] Imported new block headers count=2048 elapsed=1.536s number=7,348,512 hash=d769ac..4dfae8 age=4mo3w4d geth_1 | INFO [12-28|05:59:14.348] Imported new block headers count=2048 elapsed=1.532s number=7,350,560 hash=9b6b8d..057e63 age=4mo3w3d geth_1 | INFO [12-28|05:59:16.030] Imported new block headers count=2048 elapsed=1.682s number=7,352,608 hash=ad862e..f48541 age=4mo3w3d geth_1 | INFO [12-28|05:59:17.861] Imported new block headers count=2048 elapsed=1.829s number=7,354,656 hash=8b9cd7..bac493 age=4mo3w3d geth_1 | INFO [12-28|05:59:20.313] Imported new block headers count=2048 elapsed=2.451s number=7,356,704 hash=c951eb..e8f136 age=4mo3w2d geth_1 | INFO [12-28|05:59:22.152] Imported new block headers count=2048 elapsed=1.825s number=7,358,752 hash=c99b37..8cf710 age=4mo3w2d geth_1 | INFO [12-28|05:59:23.792] Imported new block headers count=2048 elapsed=1.639s number=7,360,800 hash=23c386..322159 age=4mo3w2d geth_1 | INFO [12-28|05:59:25.591] Imported new block headers count=2048 elapsed=1.798s number=7,362,848 hash=89bc0d..846849 age=4mo3w1d geth_1 | INFO [12-28|05:59:27.214] Imported new block headers count=2048 elapsed=1.655s number=7,364,896 hash=617145..1c1244 age=4mo3w1d geth_1 | INFO [12-28|05:59:28.705] Imported new block headers count=2048 elapsed=1.490s number=7,366,944 hash=f7d46b..0edb02 age=4mo3w22h geth_1 | INFO [12-28|05:59:30.797] Imported new block headers count=2048 elapsed=2.091s number=7,368,992 hash=a2d9c7..a0b5e9 age=4mo3w14h geth_1 | INFO [12-28|05:59:33.150] Imported new block headers count=2048 elapsed=2.351s number=7,371,040 hash=828c37..fd683e age=4mo3w5h geth_1 | INFO [12-28|05:59:35.250] Imported new block headers count=2048 elapsed=2.100s number=7,373,088 hash=a0beee..2ecb07 age=4mo2w6d geth_1 | INFO [12-28|05:59:37.407] Imported new block headers count=2048 elapsed=2.157s number=7,375,136 hash=60c480..be1ad3 age=4mo2w6d geth_1 | INFO [12-28|05:59:39.125] Imported new block headers count=2048 elapsed=1.717s number=7,377,184 hash=0e9e95..24f7d4 age=4mo2w6d geth_1 | INFO [12-28|05:59:42.328] Imported new block headers count=2048 elapsed=3.203s number=7,379,232 hash=30a441..a711cd age=4mo2w5d geth_1 | INFO [12-28|05:59:43.861] Imported new block headers count=1344 elapsed=1.531s number=7,380,576 hash=fd82a5..700ee6 age=4mo2w5d geth_1 | INFO [12-28|05:59:44.395] Storing CHT section=213 head=07324cb4f5bb62727d48ddc879bc6b64dd16366994072d11d6941fc0fe61016c root=085ee8c887822004a3c19cc6f842d9228beb055505a5b80d5ff18a36f3042e4e geth_1 | INFO [12-28|05:59:44.422] Upgrading chain index type=cht percentage=95
Testing the Node via Terminal Get Block Number
After a while, we can start test connecting to our node.
Testing block number, execute this command on the terminal.
curl --location --request POST \ --header 'Content-Type: application/json' \ --data-raw '{ "jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":83 }' \ 'http://localhost:8545'
It will return something like this.
{"jsonrpc":"2.0","id":83,"result":"0x7d5539"}
The result is the block number in hex format.
Now, cross check that number to Etherscan at goerli.etherscan.com. Make sure it is the same of newer with the one on the Latest Block there.
Testing the Node via Terminal Create New Account
To create a new account on the network, execute this command on the terminal.
curl --data '{"method":"personal_newAccount","params":["hunter2"],"id":1,"jsonrpc":"2.0"}' \ -H "Content-Type: application/json" -X POST http://localhost:8545
{"jsonrpc":"2.0","id":1,"result":"0xe68b77ce8e6fcc181226f56835190aaa217ae476"}The result is the wallet address in hex format. It is a valid Ethereum address and ready to be transacted on the network, like depositing, transfering, checking balance, etc.
Create another wallet for us to test the transaction.
Let say we have two address now, which are:
Account No 1: 0xe68b77ce8e6fcc181226f56835190aaa217ae476
Account No 2: 0xa72d1c60b806d76592babf625bd8cd74d2babaff
Obtaining Faucet ETH
Now let's try to fill up some ETH to those addresses. This is not a real ETH, but it's a faucet crypto and only valid on our test network, the Goerli network.
Go to https://goerlifaucet.com.
Sign up an account if required.
On the page displayed, just enter the Account No 1 address that you want to fill up the ETH to.
Then, click Send Me ETH button.
After a while, the account balance will be credited with some faucet ETH. To check it, go to Etherscan website on Goerli testnet, at https://goerli.etherscan.io, and enter the wallet address.
As we can see, the address is now has 0.2 ETH balance as we filled before.
Checking Wallet Balance Using Terminal
Go to the terminal again, and execute this command to check the balance, after we fill up from the faucet.
curl --data '{"method":"eth_getBalance","params":["0xe68b77ce8e6fcc181226f56835190aaa217ae476"],"id":1,"jsonrpc":"2.0"}' \ -H "Content-Type: application/json" -X POST localhost:8545
It will return something like this.
{ "id": 1, "jsonrpc": "2.0", "result": "0x0234c8a3397aab58" }
The result is the wallet balance in hex format.
Test Transfer Balance
Now, let's try to transfer the wallet balance from Account No 1 to Account No2.
curl --data '{"method":"eth_sendTransaction", "params":[{ "from":"0xe68b77ce8e6fcc181226f56835190aaa217ae476",
"to":"0xa72d1c60b806d76592babf625bd8cd74d2babaff",
"gas":"0x76c0","gasPrice":"0x9184e72a000",
"value":"0x9184e72a",
"data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}],
"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545
It will return something like this.
{ "id": 1, "jsonrpc": "2.0", "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" }
Testing the Node via Metamask
Now, lets try to connect our node via Metamask.
Click on the Metamask plugin icon on Chrome browser.
Click Settings menu.
Click Networks menu.
Click Add a network manually.
Network name: Localhost
New RPC URL: http://localhost:8545
Chain ID: 5 (goerli testnet)
Currency Symbol: ETH
Block explorer URL: https://goerli.etherscan.io
Click Save.
Great! Now, our metamask is connecting locally to our node.
Try to create new Account, initially it will have 0 balance.
Try to query the address balance from terminal and make sure the address is valid and accessible.
Congratulations!
--
Ok, those are the steps to run Ethereum Node docker stack and services.
Please consider to like, share, and subscribe our channel if you find it useful, as we will update the topics of Building E-wallet Exchange system with Odoo regularly.
Thanks for watching.