# 0G Validator Node

### Installation <a href="#installation" id="installation"></a>

Install dependencies, if needed

```bash
sudo apt update && \
sudo apt install curl git jq build-essential gcc unzip wget lz4 -y
```

Install go, if needed

```bash
cd $HOME && \
ver="1.22.0" && \
wget "https://golang.org/dl/go$ver.linux-amd64.tar.gz" && \
sudo rm -rf /usr/local/go && \
sudo tar -C /usr/local -xzf "go$ver.linux-amd64.tar.gz" && \
rm "go$ver.linux-amd64.tar.gz" && \
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> ~/.bash_profile && \
source ~/.bash_profile && \
go version
```

Build 0gchaind binary from source

```bash
git clone -b v0.3.0 https://github.com/0glabs/0g-chain.git
cd 0g-chain
make install
0gchaind version
```

Setup your variable settings

```bash
echo 'export MONIKER="My_Node"' >> ~/.bash_profile
echo 'export CHAIN_ID="zgtendermint_16600-2"' >> ~/.bash_profile
echo 'export WALLET_NAME="wallet"' >> ~/.bash_profile
echo 'export RPC_PORT="26657"' >> ~/.bash_profile
source $HOME/.bash_profile
```

Initialize node & create home directory for .0gchain

```bash
cd $HOME
0gchaind init $MONIKER --chain-id $CHAIN_ID
0gchaind config chain-id $CHAIN_ID
0gchaind config node tcp://localhost:$RPC_PORT
0gchaind config keyring-backend os # You can set it to "test" so you will not be asked for a password
```

Download genesis file

```
wget https://github.com/0glabs/0g-chain/releases/download/v0.2.3/genesis.json -O $HOME/.0gchain/config/genesis.json
```

Set 0G chain seeds

```
SEEDS="81987895a11f6689ada254c6b57932ab7ed909b6@54.241.167.190:26656,010fb4de28667725a4fef26cdc7f9452cc34b16d@54.176.175.48:26656,e9b4bc203197b62cc7e6a80a64742e752f4210d5@54.193.250.204:26656,68b9145889e7576b652ca68d985826abd46ad660@18.166.164.232:26656" && \
sed -i.bak -e "s/^seeds *=.*/seeds = \"${SEEDS}\"/" $HOME/.0gchain/config/config.toml
```

Confirm your ports (These are standard values, feel free to edit port(s) you wish to use)

```
EXTERNAL_IP=$(wget -qO- eth0.me) \
PROXY_APP_PORT=26658 \
P2P_PORT=26656 \
PPROF_PORT=6060 \
API_PORT=1317 \
GRPC_PORT=9090 \
GRPC_WEB_PORT=9091
```

Set required variable in config.toml & app.toml for your node

```
sed -i \
    -e "s/\(proxy_app = \"tcp:\/\/\)\([^:]*\):\([0-9]*\).*/\1\2:$PROXY_APP_PORT\"/" \
    -e "s/\(laddr = \"tcp:\/\/\)\([^:]*\):\([0-9]*\).*/\1\2:$RPC_PORT\"/" \
    -e "s/\(pprof_laddr = \"\)\([^:]*\):\([0-9]*\).*/\1localhost:$PPROF_PORT\"/" \
    -e "/\[p2p\]/,/^\[/{s/\(laddr = \"tcp:\/\/\)\([^:]*\):\([0-9]*\).*/\1\2:$P2P_PORT\"/}" \
    -e "/\[p2p\]/,/^\[/{s/\(external_address = \"\)\([^:]*\):\([0-9]*\).*/\1${EXTERNAL_IP}:$P2P_PORT\"/; t; s/\(external_address = \"\).*/\1${EXTERNAL_IP}:$P2P_PORT\"/}" \
    $HOME/.0gchain/config/config.toml
```

```
sed -i \
    -e "/\[api\]/,/^\[/{s/\(address = \"tcp:\/\/\)\([^:]*\):\([0-9]*\)\(\".*\)/\1\2:$API_PORT\4/}" \
    -e "/\[grpc\]/,/^\[/{s/\(address = \"\)\([^:]*\):\([0-9]*\)\(\".*\)/\1\2:$GRPC_PORT\4/}" \
    -e "/\[grpc-web\]/,/^\[/{s/\(address = \"\)\([^:]*\):\([0-9]*\)\(\".*\)/\1\2:$GRPC_WEB_PORT\4/}" \
    $HOME/.0gchain/config/app.toml
```

Pruning (Optional to save storage space)

```
sed -i \
    -e "s/^pruning *=.*/pruning = \"custom\"/" \
    -e "s/^pruning-keep-recent *=.*/pruning-keep-recent = \"100\"/" \
    -e "s/^pruning-interval *=.*/pruning-interval = \"10\"/" \
    "$HOME/.0gchain/config/app.toml"
```

Set min gas price

```
sed -i "s/^minimum-gas-prices *=.*/minimum-gas-prices = \"0ua0gi\"/" $HOME/.0gchain/config/app.toml
```

Enable indexer

```
sed -i "s/^indexer *=.*/indexer = \"kv\"/" $HOME/.0gchain/config/config.toml
```

Create 0gd service for your node to run in the background

```
sudo tee /etc/systemd/system/0gd.service > /dev/null <<EOF
[Unit]
Description=0G Node
After=network.target

[Service]
User=$USER
Type=simple
ExecStart=$(which 0gchaind) start --home $HOME/.0gchain
Restart=on-failure
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF
```

Start node

```
sudo systemctl daemon-reload && \
sudo systemctl enable 0gd && \
sudo systemctl restart 0gd && \
sudo journalctl -u 0gd -f -o cat
```

**Check for your syncing progress**

```
0gchaind status | jq '{ latest_block_height: .sync_info.latest_block_height, catching_up: .sync_info.catching_up }'
```

The result should be **`"catching_up": false`** when your node is fully synced

Result example

```
{
  "latest_block_height": "419865",
  "catching_up": false
}
```

NodeGuru's explorer for checking latest block height [here](https://testnet.0g.explorers.guru/)

## Create wallet

```
0gchaind keys add $WALLET_NAME --eth

# DO NOT FORGET TO SAVE THE SEED PHRASE & YOUR PASSPHRASE YOU SET FOR THIS WALLET
# You can add --recover flag to restore existing key instead of creating
```

**Extract the 0x address and use it for receiving testnet token**

```
echo "0x$(0gchaind debug addr $(0gchaind keys show $WALLET_NAME -a) | grep hex | awk '{print $3}')"
```

&#x20;**Request for Testnet token**

\| [Faucet](https://faucet.0g.ai/) | - use your 0x address to request

Check your wallet balance (node must be synced in order to see the current balance)

```
0gchaind q bank balances $(0gchaind keys show $WALLET_NAME -a) 
```

Result example - 1 A0GI = 1,000,000 ua0gi

```
balances:
- amount: "41694146"
  denom: ua0gi
pagination:
  next_key: null
  total: "0"
```

## &#x20;**Create validator**

```
0gchaind tx staking create-validator \
--amount=1000000ua0gi \
--pubkey=$(0gchaind tendermint show-validator) \
--moniker="$MONIKER" \
--chain-id=zgtendermint_16600-2 \
--commission-rate="0.10" \
--commission-max-rate="0.20" \
--commission-max-change-rate="0.01" \
--details="" \
--website="" \
--min-self-delegation="1" \
--from="$WALLET_NAME" \
--gas=auto \
--gas-adjustment=1.4 \
-y
```

Once your validator is created you can look up your validator [here](https://testnet.0g.explorers.guru/validators). Most likely it will be in `inactive` set as you will need enough stake to reach top 125 TVL validator. This is normal \~\~\~

**Run curl test to check for your RPC port if it's works properly**

```
# set EXTERNAL_IP variable
EXTERNAL_IP=$(wget -qO- eth0.me)

# query for current block height (json-rpc)
curl -X POST http://$EXTERNAL_IP:8545 -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

# query for Net version (json-rpc)
curl -X POST http://$EXTERNAL_IP:8545 -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"net_version","params":[],"id":1}'
```

Result example

Current block height

```
{"jsonrpc":"2.0","id":1,"result":"0x66972"}
```

Net version (evm chain-id)

```
{"jsonrpc":"2.0","id":1,"result":"16600"}
```

## Upgrade Your Node <a href="#upgrade-your-node" id="upgrade-your-node"></a>

At height 574000

```
cd $HOME
wget -O 0gchaind https://zgchaind-test.s3.ap-east-1.amazonaws.com/0gchaind-linux-v0.3.0
chmod +x $HOME/0gchaind
sudo mv $HOME/0gchaind $HOME/go/bin/
sudo systemctl restart 0gd
```

Check log

```
tail -f -n 100 $HOME/.0gchain/log/chain.log
```

## Congratulation!!&#x20;

Now you have completed your node for 0gchain and we will move on to creating your storage node next.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://services.dongqn.com/0g-validator-node.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
