# 0G Storage Node Setup Guide

### Prerequisite <a href="#prerequisite" id="prerequisite"></a>

Please complete your [Validator node](/node-guides/quick-start/zerogravity-0g/validator-node-setup-guide.md) before proceed this setup

Make sure that your \[json-rpc] is working properly by running [this test ](/node-guides/quick-start/zerogravity-0g/validator-node-setup-guide.md#run-curl-test-to-check-for-your-rpc-port-if-its-works-properly)

0G Storage and DA services interact with on-chain contracts for blob root confirmation and PoRA mining.

For official deployed contract addresses, visit [this page](https://docs.0g.ai/0g-doc/docs/contract-addresses).

### 0G Storage Node <a href="#storage-node" id="storage-node"></a>

```yaml
# Current version used in doc
Binary: zgs_node
Chain id: zgtendermint_16600-2
Version: 0.4.1
Service Name: zgs.service
```

#### ⚙️ **Hardware Requirement**

```yaml
- Memory: 16 GB RAM
- CPU: 4 cores
- Disk: 500GB / 1T NVME SSD
- Bandwidth: 500 MBps for Download / Upload
```

#### System updates, installation of required dependencies

```bash
sudo apt-get update
sudo apt-get install clang cmake build-essential
```

#### Install rust

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustc --version
```

*When prompted choice of 1,2 and 3 just hit enter to continue*

#### Install the latest GO

```bash
# install the latest GO
cd $HOME && \
ver="1.22.4" && \
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" >> $HOME/.bash_profile && \
source $HOME/.bash_profile && \
go version
```

#### Build zgs\_node binary from source with rust

```bash
git clone https://github.com/0glabs/0g-storage-node.git
cd $HOME/0g-storage-node
git checkout tags/v0.4.1
git submodule update --init
cargo build --release
```

#### Setup your variable settings

```bash
export ZGS_LOG_DIR="$HOME/0g-storage-node/run/log"
export ZGS_LOG_CONFIG_FILE="$HOME/0g-storage-node/run/log_config"
export LOG_CONTRACT_ADDRESS="0xbD2C3F0E65eDF5582141C35969d66e34629cC768"
export MINE_CONTRACT="0x6815F41019255e00D6F34aAB8397a6Af5b6D806f"
export ZGS_LOG_SYNC_BLOCK=595059 # flow contract deployed block
export WATCH_LOOP_WAIT_TIME_MS=1000 # you can adjust this value from 500 - 50000, the higher number indicate longer watch loop helps to reduce rpc call preventing rate limit. 
```

```bash
# Extract Ethereum private key from the specified wallet
0gchaind keys unsafe-export-eth-key $WALLET_NAME
read -sp "Enter your extracted private key: " PRIVATE_KEY && echo

# Update the miner_key in the config.toml file
sed -i 's|^miner_key = ""|miner_key = "'"$PRIVATE_KEY"'"|' $HOME/0g-storage-node/run/config.toml
```

Set parameters in config.toml

```bash
# Fetch storage node's IP
ZGS_IP=$(wget -qO- eth0.me)

# Update parameters for storage node in config.toml
sed -i '
s|# network_dir = "network"|network_dir = "network"|g
s|# network_enr_tcp_port = 1234|network_enr_tcp_port = 1234|g
s|# network_enr_udp_port = 1234|network_enr_udp_port = 1234|g
s|# network_libp2p_port = 1234|network_libp2p_port = 1234|g
s|# network_discovery_port = 1234|network_discovery_port = 1234|g
s|# rpc_enabled = true|rpc_enabled = true|g
s|# db_dir = "db"|db_dir = "db"|g
s|# log_config_file = "log_config"|log_config_file = "log_config"|g
s|# log_directory = "log"|log_directory = "log"|g
s|# watch_loop_wait_time_ms = 500|watch_loop_wait_time_ms = 15000|g
s|network_enr_address = ""|network_enr_address = "'"$ZGS_IP"'"|g
' $HOME/0g-storage-node/run/config.toml

# Update specific settings with set variables
sed -i '
s|^log_sync_start_block_number = .*|log_sync_start_block_number = '"$ZGS_LOG_SYNC_BLOCK"'|g
s|^log_config_file = .*|log_config_file = "'"$ZGS_LOG_CONFIG_FILE"'"|g
s|^log_directory = .*|log_directory = "'"$ZGS_LOG_DIR"'"|g
s|^mine_contract_address = .*|mine_contract_address = "'"$MINE_CONTRACT"'"|g
s|^log_contract_address = .*|log_contract_address = "'"$LOG_CONTRACT_ADDRESS"'"|g
s|^watch_loop_wait_time_ms = .*|watch_loop_wait_time_ms = '"$WATCH_LOOP_WAIT_TIME_MS"'|g
' $HOME/0g-storage-node/run/config.toml
```

(Recommended) Set `blockchain_rpc_endpoint` to your validator's (json-rpc endpoint)

```bash
JSON_PORT=8545 # replace with the port you want to use

BLOCKCHAIN_RPC_ENDPOINT="http://$(wget -qO- eth0.me):$JSON_PORT"
sed -i 's|^blockchain_rpc_endpoint = ".*"|blockchain_rpc_endpoint = "'"$BLOCKCHAIN_RPC_ENDPOINT"'"|' $HOME/0g-storage-node/run/config.toml
echo "export BLOCKCHAIN_RPC_ENDPOINT=\"$BLOCKCHAIN_RPC_ENDPOINT\"" >> ~/.bash_profile
echo "BLOCKCHAIN_RPC_ENDPOINT: $BLOCKCHAIN_RPC_ENDPOINT"
```

#### Create zgs service (storage node) for your node to run in the background

```bash
sudo tee /etc/systemd/system/zgs.service > /dev/null <<EOF
[Unit]
Description=ZGS Node
After=network.target

[Service]
User=$USER
WorkingDirectory=$HOME/0g-storage-node/run
ExecStart=$HOME/0g-storage-node/target/release/zgs_node --config $HOME/0g-storage-node/run/config.toml
Restart=on-failure
RestartSec=10
LimitNOFILE=65535

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

#### Start Storage node

```bash
sudo systemctl daemon-reload && \
sudo systemctl enable zgs && \
sudo systemctl restart zgs
```

#### Stop Storage node - (if you wish to stop the service)

```bash
sudo systemctl stop zgs
```

#### Check Storage node log

```bash
# List all logs avialble on your machine
ls ~/0g-storage-node/run/log/

# Monitor the latest log available (auto-fetch date)
tail -f ~/0g-storage-node/run/log/zgs.log.$(TZ=UTC date +%Y-%m-%d)
```

You will need to change the `date` if you wish to see log(s) on a specific date.

for an example

```bash
tail -f ~/0g-storage-node/run/log/zgs.log.2024-06-04
```

#### Check log tx\_seq storage sync

```bash
tail -f ~/0g-storage-node/run/log/zgs.log.$(TZ=UTC date +%Y-%m-%d) | grep tx_seq
```

Congrats! Your storage node is done \~\~&#x20;

Test Storage Node with [Storage CLI](/node-guides/quick-start/zerogravity-0g/0g-storage-node-setup-guide/0g-storage-cli.md) to check its purfection moving along

<figure><img src="/files/lFlPyXb1AfUvWqAMU9zX" alt="" width="375"><figcaption><p>nekohime ~~</p></figcaption></figure>


---

# 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://docs.nodecattel.xyz/node-guides/quick-start/zerogravity-0g/0g-storage-node-setup-guide.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.
