> For the complete documentation index, see [llms.txt](https://cryptomolot.gitbook.io/cryptomolot-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cryptomolot.gitbook.io/cryptomolot-docs/testnets/0g-zero-gravity/0g-storage-node.md).

# 0G Storage Node

## Resources

| Website | <https://0g.ai/>                                      |
| ------- | ----------------------------------------------------- |
| Github  | <https://github.com/0glabs>                           |
| x.com   | [https://x.com/0G\_labs](https://twitter.com/0G_labs) |
| Discord | <https://discord.com/invite/0glabs>                   |
| Docs    | <https://docs.0g.ai/0g-doc>                           |

## Prerequisite

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

This step is performed after your [validator](https://app.gitbook.com/o/CCRLLakO01pbPnsbSqvj/s/socsWgfdMBUSXoC8Z3Gv/~/changes/35/testnets/0g-zero-gravity/0g-zero-gravity-validator-node) has been installed and created.

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

## Hardware requirements

<table data-view="cards"><thead><tr><th>CPU</th><th>RAM</th><th>Storage</th><th>Network</th><th>OS</th></tr></thead><tbody><tr><td>4 cores</td><td>16 GB</td><td>1 TB NVME</td><td>500 MBps</td><td>Linux (Ubuntu 20.04 x64)</td></tr></tbody></table>

## Installation 💾

Install dependencies

```bash
sudo apt update && sudo apt upgrade -y
sudo apt install curl git wget htop tmux build-essential jq make lz4 gcc unzip -y
```

Install Rust

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env

cargo --version
rustc --version
```

Install GO 1.22.2

```bash
sudo rm -rf /usr/local/go && \
curl -L https://go.dev/dl/go1.22.2.linux-amd64.tar.gz | sudo tar -xzf - -C /usr/local && \
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> $HOME/.bash_profile && \
source .bash_profile && \
go version
```

Build binary from source

```bash
git clone -b v1.0.0 https://github.com/0glabs/0g-storage-node.git

cd $HOME/0g-storage-node
git stash
git fetch --all --tags
git checkout 347cd3e
git submodule update --init
cargo build --release

cp $HOME/0g-storage-node/run/config-testnet-turbo.toml $HOME/0g-storage-node/run/config.toml
```

check zgs version

```bash
$HOME/0g-storage-node/target/release/zgs_node --version
```

Set vars. you found more from official docs

```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="0xbD75117F80b4E22698D0Cd7612d92BDb8eaff628"
export MINE_CONTRACT="0x3A0d1d67497Ad770d6f72e7f4B8F0BAbaa2A649C"
export REWARD_CONTRACT="0xd3D4D91125D76112AE256327410Dd0414Ee08Cb4"
export ZGS_LOG_SYNC_BLOCK=326165
```

Set Ethereum private key. Your private key (64 chars, no '0x' prefix, include leading zeros): Your private key (without the `0x` prefix) if you want to participate in PoRA mining and earn rewards.

&#x20;After entering the next command, a field will appear in which you should enter the key you received in the previous step. Note that the text you enter will not be displayed.

```bash
read -sp "Enter your extracted private key: " PRIVATE_KEY && echo
```

Set the miner\_key in the config.toml file

```bash
sed -i 's|^miner_key = ""|miner_key = "'"$PRIVATE_KEY"'"|' $HOME/0g-storage-node/run/config.toml
```

Set var the Storage Node IP address

```bash
ZGS_IP=$(wget -qO- eth0.me)
```

Edit the storage node config

```bash
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|# network_enr_address = ""|network_enr_address = "'"$ZGS_IP"'"|g
' $HOME/0g-storage-node/run/config.toml
```

```bash
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|^reward_contract_address = .*|reward_contract_address = "'"$REWARD_CONTRACT"'"|g
' $HOME/0g-storage-node/run/config.toml
```

Update boot nodes addresses

```bash
sed -i 's|^network_boot_nodes = .*|network_boot_nodes = ["/ip4/47.251.117.133/udp/1234/p2p/16Uiu2HAmTVDGNhkHD98zDnJxQWu3i1FL1aFYeh9wiQTNu4pDCgps","/ip4/47.76.61.226/udp/1234/p2p/16Uiu2HAm2k6ua2mGgvZ8rTMV8GhpW71aVzkQWy7D37TTDuLCpgmX","/ip4/47.251.79.83/udp/1234/p2p/16Uiu2HAkvJYQABP1MdvfWfUZUzGLx1sBSDZ2AT92EFKcMCCPVawV","/ip4/47.238.87.44/udp/1234/p2p/16Uiu2HAmFGsLoajQdEds6tJqsLX7Dg8bYd2HWR4SbpJUut4QXqCj","/ip4/47.251.78.104/udp/1234/p2p/16Uiu2HAmSe9UWdHrqkn2mKh99b9DwYZZcea6krfidtU3e5tiHiwN","/ip4/47.76.30.235/udp/1234/p2p/16Uiu2HAm5tCqwGtXJemZqBhJ9JoQxdDgkWYavfCziaqaAYkGDSfU"]|g' ~/0g-storage-node/run/config.toml
```

Set `blockchain_rpc_endpoint` from your validator's (json-rpc endpoint). To connect your storage node to the validator.

{% hint style="info" %}
You can use the json-rpc of your validator (which you can see in the $HOME/.0gchain/config/app.toml file) or use any available from the community.<br>

You should also have the indexer enabled in the validator config:\
sed -i -e "s/^indexer \*=.\*/indexer = \\"kv"/" $HOME/.0gchain/config/config.toml
{% endhint %}

Official 0g rpc endpoint:

```bash
BLOCKCHAIN_RPC_ENDPOINT="https://evmrpc-testnet.0g.ai"
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
```

Create a service file

```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 the node

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

## Useful commands ⚙️

Stop the storage node

```bash
sudo systemctl stop zgs
```

Check list of logs

```bash
ls ~/0g-storage-node/run/log/
```

Check logs on a specific date. For example:

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

Check the latest logs file

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

Check sync status

```bash
while true; do 
    response=$(curl -s -X POST http://localhost:5678 -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"zgs_getStatus","params":[],"id":1}')
    logSyncHeight=$(echo $response | jq '.result.logSyncHeight')
    connectedPeers=$(echo $response | jq '.result.connectedPeers')
    echo -e "logSyncHeight: \033[32m$logSyncHeight\033[0m, connectedPeers: \033[34m$connectedPeers\033[0m"
    sleep 5; 
done
```

Check version

```bash
cd $HOME/0g-storage-node && git log --decorate=short --oneline | grep "tag: v" | head -n 1 && git log -1 --pretty=oneline
```

## Delete node 🗑️

```bash
sudo systemctl stop zgs && sudo systemctl disable zgs
sudo rm -rf /etc/systemd/system/zgs.service
sudo rm $(which zgs)
sudo rm -rf $HOME/0g-storage-node
```
