Skip to content

Deploying Ergo

Introduction

Ergo is a resilient blockchain platform for contractual money that builds on Bitcoin’s UTXO model while introducing powerful smart contract capabilities through ErgoScript. Designed with a research-driven approach, Ergo combines proven cryptographic techniques with innovative features like storage rent, NiPoPoWs (Non-Interactive Proofs of Proof-of-Work), and a memory-hard Proof-of-Work algorithm called Autolykos2.

The Ergo reference client (node) is primarily written in Scala and provides a complete implementation of the Ergo protocol. Running an Ergo node contributes to the network’s decentralization and security while giving you direct access to the blockchain, the ability to validate transactions independently, and participate in mining or develop ErgoScript applications.

Why Ergo?

Ergo stands out with its unique approach to blockchain design and economics:

  • Contractual Money: Build sophisticated financial agreements with ErgoScript’s multi-stage UTXO contracts
  • Proven Cryptography: Based on solid cryptographic foundations with peer-reviewed research
  • Memory-Hard PoW: Autolykos2 algorithm resists ASICs and promotes fair mining distribution
  • Storage Rent: Innovative economic model with mandatory storage-rent to prevent UTXO bloat
  • NiPoPoW Support: Efficient light clients with Non-Interactive Proofs of Proof-of-Work
  • Stateless Client Support: Run a node without storing the full UTXO set
  • ErgoScript: Powerful scripting language based on Σ-protocols for zero-knowledge proofs
  • Fixed Supply: True fixed supply of 97.7 million ERG with storage rent recirculation
  • Research-Driven: Built on academic research with multiple peer-reviewed papers
  • UTXO Model: Inherits Bitcoin’s proven transaction model with enhanced capabilities
  • Alternative Transactional Language: More expressive than Bitcoin Script, safer than account-based models
  • Multiple Sync Modes: Full archival, pruned, light, and digest modes for different resource needs
  • Bootstrap Options: Fast sync with UTXO snapshots and NiPoPoW bootstrapping
  • Active Development: Over 50 contributors with continuous protocol improvements
  • Open Source: CC0-1.0 licensed with transparent development

Ergo is ideal for developers building decentralized applications, miners seeking fair distribution, researchers exploring blockchain economics, and anyone wanting to participate in a research-driven blockchain platform.

Why Deploy on Klutch.sh?

Deploying an Ergo node on Klutch.sh offers significant advantages:

  • Simplified Deployment: Deploy directly from GitHub with automatic Docker detection
  • Persistent Storage: Built-in volume support for blockchain data (50GB+ recommended)
  • TCP Connectivity: Easy P2P networking configuration for blockchain synchronization
  • Resource Scaling: Adjust CPU and memory as your node requirements grow
  • HTTPS Access: Secure API access with automatic SSL certificates
  • Environment Management: Secure configuration of wallet keys and network settings
  • High Availability: Reliable infrastructure ensures your node stays synchronized
  • Custom Domains: Use your own domain for API and explorer access

Prerequisites

Before deploying an Ergo node, ensure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your deployment configuration
  • Basic familiarity with Docker and blockchain concepts
  • Understanding of blockchain nodes and P2P networking
  • At least 50GB available storage for blockchain data (100GB+ recommended for full archival)
  • Minimum 4GB RAM for stable operation (8GB recommended)

Understanding Ergo Node Modes

Ergo supports multiple operational modes depending on your resources and requirements:

Full Archival Node

Stores the complete blockchain history including all transactions and proofs. Requires the most storage (50GB+) but provides full validation capabilities.

Pruned Full Node

Maintains full security while reducing storage requirements by keeping only recent blocks with full data. Recommended for most users with limited storage.

Light Full Node

Stores only recent UTXO set snapshots and block headers. Validates transactions using authenticated data structures. Lowest storage requirements.

Digest Mode

Maintains only state root hashes and validates transactions via ADProofs. Suitable for very resource-constrained environments.

Preparing Your Repository

Create a new GitHub repository for your Ergo node deployment with the following structure:

ergo-node/
├── Dockerfile
├── application.conf
├── .env.example
├── .dockerignore
├── README.md
└── .gitignore

Dockerfile

Create a production-ready Dockerfile for Ergo:

FROM ergoplatform/ergo:latest
# Set working directory
WORKDIR /home/ergo
# Environment variables for heap size
ENV MAX_HEAP=3G
# Copy custom configuration if needed
# COPY application.conf /home/ergo/.ergo/application.conf
# Expose ports
# 9020: P2P network communication
# 9052: REST API
# 9053: Panel API (if enabled)
EXPOSE 9020 9052 9053
# Health check for node synchronization
HEALTHCHECK --interval=60s --timeout=10s --start-period=300s --retries=3 \
CMD curl -f http://localhost:9052/info || exit 1
# Volume for blockchain data
VOLUME ["/home/ergo/.ergo"]
# The base image already sets the entrypoint
# ENTRYPOINT ["java", "-jar", "/home/ergo/ergo.jar"]

Configuration File Template

Create an application.conf.example file for node configuration:

ergo {
# Directory for node data
directory = "/home/ergo/.ergo"
# Network settings
networkType = "mainnet" # or "testnet"
node {
# Mining configuration (set to true if mining)
mining = false
# State type: "utxo" (full node) or "digest" (light node)
stateType = "utxo"
# Enable extra index for explorer-like functionality
extraIndex = false
# Number of blocks to keep with full data (-1 for all)
blocksToKeep = -1
# Fast sync with UTXO bootstrap
utxoBootstrap = true
# Fast sync with NiPoPoW
nipopowBootstrap = true
# Transaction verification
verifyTransactions = true
# Number of state snapshot diffs to keep
keepVersions = 200
}
# Scorex settings for P2P networking
scorex {
network {
# Network name
networkName = "ergo-mainnet-5.0"
# Bind address for P2P
bindAddress = "0.0.0.0:9020"
# Known peers for initial sync
knownPeers = [
"213.239.193.208:9020",
"88.198.13.202:9020",
"159.65.11.55:9020",
"136.243.186.58:9020"
]
# Maximum number of connections
maxConnections = 30
}
restApi {
# Bind address for REST API
bindAddress = "0.0.0.0:9052"
# API key for protected endpoints
apiKeyHash = null # Set via environment variable
# CORS settings
corsAllowedOrigin = "*"
}
}
# Wallet settings
wallet {
# Seed strength in bits
seedStrengthBits = 160
# Mnemonic phrase language
mnemonicPhraseLanguage = "english"
# Keep spending proofs for wallet
keepSpentBoxes = false
# Default transaction fee
defaultTransactionFee = 1000000
}
}

Environment Variables File

Create a .env.example file:

Terminal window
# Node Configuration
ERGO_NETWORK=mainnet # or testnet
MAX_HEAP=3G # Java heap size (2G, 3G, 4G, etc.)
# API Configuration
API_KEY_HASH= # SHA256 hash of your API key for protected endpoints
# Node Mode Settings
# STATE_TYPE=utxo # utxo (full) or digest (light)
# MINING_ENABLED=false
# EXTRA_INDEX=false
# Network Configuration
# P2P_BIND_ADDRESS=0.0.0.0:9020
# API_BIND_ADDRESS=0.0.0.0:9052
# Bootstrap Options
# UTXO_BOOTSTRAP=true # Fast sync with UTXO snapshots
# NIPOPOW_BOOTSTRAP=true # Fast sync with NiPoPoWs
# Storage Configuration
# BLOCKS_TO_KEEP=-1 # -1 for all blocks, or number of recent blocks
# Wallet Configuration (if using node wallet)
# WALLET_SEED= # Your wallet mnemonic (keep this secret!)
# WALLET_PASSWORD= # Password for wallet encryption
# Mining Configuration (if mining)
# MINING_PUBLIC_KEY= # Your mining reward address
# Optional: Custom known peers (comma-separated)
# KNOWN_PEERS=peer1:9020,peer2:9020
# Optional: Data directory (defaults to /home/ergo/.ergo)
# ERGO_DATA_DIR=/home/ergo/.ergo

Docker Ignore File

Create a .dockerignore file:

.git
.gitignore
.env
.env.example
*.md
README.md
docker-compose.yml
.vscode
.idea
*.log
.DS_Store
.ergo/
data/

Git Ignore File

Create a .gitignore file:

.env
*.log
.DS_Store
.vscode/
.idea/
.ergo/
data/
wallet.dat
*.key
node_modules/

Deploying on Klutch.sh

  1. Create a New Project

    Log in to the Klutch.sh dashboard and create a new project for your Ergo node deployment.

  2. Connect Your GitHub Repository

    In your Klutch.sh project:

    1. Navigate to the Apps section
    2. Click “Create New App”
    3. Select GitHub as your source
    4. Choose the repository containing your Ergo Dockerfile
    5. Select the branch you want to deploy (typically main or master)
  3. Configure Build Settings

    Klutch.sh will automatically detect your Dockerfile. No additional configuration needed for the build process.

  4. Set Traffic Type

    In the deployment settings:

    1. Select TCP as the traffic type for P2P networking
    2. Set the internal port to 9020 for P2P communication
    3. Klutch.sh will route traffic to port 8000 externally

    Note: For API access (port 9052), you may want to deploy a separate HTTP service or configure additional port mappings.

  5. Configure Environment Variables

    In your Klutch.sh app settings, add the following environment variables:

    Required Variables:

    Terminal window
    ERGO_NETWORK=mainnet
    MAX_HEAP=3G

    Optional Variables (Recommended):

    Terminal window
    API_KEY_HASH=your_sha256_api_key_hash
    UTXO_BOOTSTRAP=true
    NIPOPOW_BOOTSTRAP=true

    Mining Variables (if mining):

    Terminal window
    MINING_ENABLED=true
    MINING_PUBLIC_KEY=your_ergo_address

    Mark sensitive values like API_KEY_HASH and WALLET_SEED as secret.

  6. Attach Persistent Volume

    Ergo nodes require significant storage for blockchain data:

    1. In your Klutch.sh app settings, navigate to Volumes
    2. Click “Add Volume”
    3. Set the mount path to /home/ergo/.ergo
    4. Choose an appropriate size:
      • Full Archival Node: 100GB minimum (150GB recommended)
      • Pruned Full Node: 50GB minimum (75GB recommended)
      • Light Full Node: 10GB minimum (20GB recommended)
    5. Save the volume configuration
  7. Configure Resource Allocation

    Set appropriate compute resources:

    Minimum Requirements:

    • CPU: 2 cores
    • RAM: 4GB

    Recommended for Production:

    • CPU: 4 cores
    • RAM: 8GB

    For Mining:

    • CPU: 4-8 cores
    • RAM: 8-16GB
  8. Deploy the Application

    Click “Deploy” to start the deployment process. Klutch.sh will:

    1. Pull your code from GitHub
    2. Build the Docker image
    3. Configure networking and volumes
    4. Start your Ergo node

    The initial deployment may take 5-10 minutes. Initial blockchain synchronization will take several hours to days depending on the mode.

  9. Verify Deployment

    Once deployed, verify your Ergo node:

    Terminal window
    # Check node info (replace with your app URL)
    curl http://example-app.klutch.sh:8000/info
    # Check sync status
    curl http://example-app.klutch.sh:8000/info | jq '.fullHeight, .headersHeight'

    You should receive a JSON response with node information.

Initial Configuration

Monitoring Synchronization

After deployment, your node will begin synchronizing with the Ergo blockchain. Monitor the sync progress:

  1. Check Sync Status via API:

    Terminal window
    # Get current sync status
    curl -X GET "http://example-app.klutch.sh:8000/info" | jq '{
    fullHeight: .fullHeight,
    headersHeight: .headersHeight,
    isMining: .isMining,
    peersCount: .peersCount
    }'
  2. Understanding Sync Metrics:

    • fullHeight: Number of fully validated blocks
    • headersHeight: Number of downloaded block headers
    • peersCount: Number of connected peers

    When fullHeight equals headersHeight, your node is fully synchronized.

  3. Expected Sync Times:

    • With UTXO Bootstrap + NiPoPoW: 4-8 hours
    • Without Bootstrap (full sync): 2-7 days
    • Light mode: 1-2 hours

Setting Up the Node Wallet

Ergo nodes include a built-in wallet for managing funds:

  1. Initialize Wallet:

    Terminal window
    # Generate new wallet
    curl -X POST "http://example-app.klutch.sh:8000/wallet/init" \
    -H "Content-Type: application/json" \
    -d '{
    "pass": "your_secure_password",
    "mnemonicPass": ""
    }'

    Response includes your mnemonic seed phrase. Store this securely offline!

  2. Restore Existing Wallet:

    Terminal window
    # Restore from mnemonic
    curl -X POST "http://example-app.klutch.sh:8000/wallet/restore" \
    -H "Content-Type: application/json" \
    -d '{
    "pass": "your_secure_password",
    "mnemonic": "your twelve or more word seed phrase",
    "mnemonicPass": ""
    }'
  3. Unlock Wallet:

    Terminal window
    # Unlock for transactions
    curl -X POST "http://example-app.klutch.sh:8000/wallet/unlock" \
    -H "Content-Type: application/json" \
    -d '{
    "pass": "your_secure_password"
    }'
  4. Get Wallet Addresses:

    Terminal window
    # Get receiving addresses
    curl -X GET "http://example-app.klutch.sh:8000/wallet/addresses" \
    -H "api_key: your_api_key"

Configuring API Access

Secure your node’s REST API:

  1. Generate API Key:

    Terminal window
    # Create a strong API key
    openssl rand -hex 32
  2. Create API Key Hash:

    Terminal window
    # Hash the API key with SHA256
    echo -n "your_api_key" | sha256sum
  3. Update Environment Variables:

    Add the API key hash to your Klutch.sh environment variables:

    Terminal window
    API_KEY_HASH=your_sha256_hash
  4. Redeploy with New Configuration:

    Redeploy your application for the API key to take effect.

  5. Test Protected Endpoints:

    Terminal window
    # Access protected endpoint
    curl -X GET "http://example-app.klutch.sh:8000/wallet/balances" \
    -H "api_key: your_api_key"

Using the Ergo Node

Querying Blockchain Data

Get Node Information:

Terminal window
curl http://example-app.klutch.sh:8000/info | jq

Get Block by Height:

Terminal window
# Get block at height 1000
curl http://example-app.klutch.sh:8000/blocks/at/1000 | jq

Get Block by ID:

Terminal window
curl http://example-app.klutch.sh:8000/blocks/BLOCK_ID_HERE | jq

Get Transaction by ID:

Terminal window
curl http://example-app.klutch.sh:8000/transactions/TX_ID_HERE | jq

Get UTXO Box by ID:

Terminal window
curl http://example-app.klutch.sh:8000/utxo/byId/BOX_ID_HERE | jq

Managing Wallet Transactions

Check Wallet Balance:

Terminal window
curl -X GET "http://example-app.klutch.sh:8000/wallet/balances" \
-H "api_key: your_api_key" | jq

Create Payment Transaction:

Terminal window
curl -X POST "http://example-app.klutch.sh:8000/wallet/payment/send" \
-H "Content-Type: application/json" \
-H "api_key: your_api_key" \
-d '{
"address": "recipient_ergo_address",
"value": 1000000000,
"fee": 1000000
}'

Get Transaction Status:

Terminal window
curl http://example-app.klutch.sh:8000/transactions/unconfirmed/byId/TX_ID | jq

Mining with Ergo Node

Enable Mining:

  1. Update Configuration:

    Add mining environment variables:

    Terminal window
    MINING_ENABLED=true
    MINING_PUBLIC_KEY=your_mining_address
  2. External Miner Setup:

    For better performance, use an external miner like ErgoStratumServer with mining software:

  3. Check Mining Status:

    Terminal window
    curl http://example-app.klutch.sh:8000/info | jq '.isMining'

Sample Code Examples

Node.js Example - Get Blockchain Info:

const fetch = require('node-fetch');
const ERGO_NODE_URL = 'http://example-app.klutch.sh:8000';
const API_KEY = 'your_api_key';
async function getNodeInfo() {
try {
const response = await fetch(`${ERGO_NODE_URL}/info`);
const data = await response.json();
console.log('Node Info:');
console.log(`- Network: ${data.network}`);
console.log(`- Full Height: ${data.fullHeight}`);
console.log(`- Headers Height: ${data.headersHeight}`);
console.log(`- Peers: ${data.peersCount}`);
console.log(`- Synced: ${data.fullHeight === data.headersHeight}`);
return data;
} catch (error) {
console.error('Error fetching node info:', error);
}
}
async function getWalletBalance() {
try {
const response = await fetch(`${ERGO_NODE_URL}/wallet/balances`, {
headers: {
'api_key': API_KEY
}
});
const data = await response.json();
console.log('Wallet Balance:');
console.log(`- Confirmed: ${data.balance / 1000000000} ERG`);
console.log(`- Unconfirmed: ${data.unconfirmedBalance / 1000000000} ERG`);
return data;
} catch (error) {
console.error('Error fetching wallet balance:', error);
}
}
async function sendTransaction(recipient, amount) {
try {
const response = await fetch(`${ERGO_NODE_URL}/wallet/payment/send`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'api_key': API_KEY
},
body: JSON.stringify({
address: recipient,
value: amount * 1000000000, // Convert ERG to nanoERG
fee: 1000000 // 0.001 ERG
})
});
const data = await response.json();
console.log('Transaction sent:', data.id);
return data;
} catch (error) {
console.error('Error sending transaction:', error);
}
}
// Usage
getNodeInfo();
getWalletBalance();

Python Example - Monitor Node Sync:

import requests
import time
ERGO_NODE_URL = "http://example-app.klutch.sh:8000"
API_KEY = "your_api_key"
def get_sync_status():
"""Get current synchronization status"""
try:
response = requests.get(f"{ERGO_NODE_URL}/info")
data = response.json()
full_height = data.get('fullHeight', 0)
headers_height = data.get('headersHeight', 0)
peers = data.get('peersCount', 0)
sync_percentage = (full_height / headers_height * 100) if headers_height > 0 else 0
return {
'full_height': full_height,
'headers_height': headers_height,
'peers': peers,
'sync_percentage': sync_percentage,
'is_synced': full_height == headers_height
}
except Exception as e:
print(f"Error getting sync status: {e}")
return None
def monitor_sync(interval=60):
"""Monitor sync progress"""
print("Monitoring Ergo node synchronization...")
print("-" * 60)
while True:
status = get_sync_status()
if status:
print(f"Blocks: {status['full_height']}/{status['headers_height']} "
f"({status['sync_percentage']:.2f}%) | "
f"Peers: {status['peers']}")
if status['is_synced']:
print("\n✓ Node is fully synchronized!")
break
time.sleep(interval)
def get_balance():
"""Get wallet balance"""
try:
headers = {'api_key': API_KEY}
response = requests.get(f"{ERGO_NODE_URL}/wallet/balances", headers=headers)
data = response.json()
confirmed = data.get('balance', 0) / 1_000_000_000
unconfirmed = data.get('unconfirmedBalance', 0) / 1_000_000_000
print(f"Wallet Balance:")
print(f" Confirmed: {confirmed:.9f} ERG")
print(f" Unconfirmed: {unconfirmed:.9f} ERG")
return data
except Exception as e:
print(f"Error getting balance: {e}")
return None
# Usage
monitor_sync(interval=30)
get_balance()

Go Example - Query Blockchain:

package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const (
ergoNodeURL = "http://example-app.klutch.sh:8000"
apiKey = "your_api_key"
)
type NodeInfo struct {
Name string `json:"name"`
Network string `json:"network"`
FullHeight int `json:"fullHeight"`
HeadersHeight int `json:"headersHeight"`
PeersCount int `json:"peersCount"`
IsMining bool `json:"isMining"`
}
type WalletBalance struct {
Balance int64 `json:"balance"`
UnconfirmedBalance int64 `json:"unconfirmedBalance"`
}
func getNodeInfo() (*NodeInfo, error) {
resp, err := http.Get(ergoNodeURL + "/info")
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var info NodeInfo
err = json.Unmarshal(body, &info)
if err != nil {
return nil, err
}
return &info, nil
}
func getWalletBalance() (*WalletBalance, error) {
client := &http.Client{}
req, err := http.NewRequest("GET", ergoNodeURL+"/wallet/balances", nil)
if err != nil {
return nil, err
}
req.Header.Add("api_key", apiKey)
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var balance WalletBalance
err = json.Unmarshal(body, &balance)
if err != nil {
return nil, err
}
return &balance, nil
}
func main() {
// Get node information
info, err := getNodeInfo()
if err != nil {
fmt.Printf("Error getting node info: %v\n", err)
return
}
fmt.Printf("Ergo Node Information:\n")
fmt.Printf("Network: %s\n", info.Network)
fmt.Printf("Full Height: %d\n", info.FullHeight)
fmt.Printf("Headers Height: %d\n", info.HeadersHeight)
fmt.Printf("Peers: %d\n", info.PeersCount)
fmt.Printf("Mining: %t\n", info.IsMining)
fmt.Printf("Synced: %t\n", info.FullHeight == info.HeadersHeight)
// Get wallet balance
balance, err := getWalletBalance()
if err != nil {
fmt.Printf("Error getting wallet balance: %v\n", err)
return
}
confirmedERG := float64(balance.Balance) / 1_000_000_000
unconfirmedERG := float64(balance.UnconfirmedBalance) / 1_000_000_000
fmt.Printf("\nWallet Balance:\n")
fmt.Printf("Confirmed: %.9f ERG\n", confirmedERG)
fmt.Printf("Unconfirmed: %.9f ERG\n", unconfirmedERG)
}

Advanced Configuration

Pruned Node Configuration

For reduced storage requirements while maintaining full security:

Update your application.conf:

ergo {
node {
stateType = "utxo"
blocksToKeep = 1440 # Keep last ~2 days of blocks
utxoBootstrap = true
nipopowBootstrap = true
}
}

This configuration keeps only recent blocks with full data while maintaining the complete UTXO set.

Digest Mode Configuration

For minimal storage (stateless client):

ergo {
node {
stateType = "digest"
blocksToKeep = 2160 # Keep last ~3 days
nipopowBootstrap = true
verifyTransactions = true
}
}

Custom Peer Configuration

Add trusted peers for better connectivity:

scorex {
network {
knownPeers = [
"213.239.193.208:9020",
"88.198.13.202:9020",
"your-peer-1:9020",
"your-peer-2:9020"
]
maxConnections = 50
}
}

Enable Explorer Features

For blockchain explorer functionality:

Terminal window
# Add to environment variables
EXTRA_INDEX=true
EXTRA_CACHE_SIZE=1000

This enables querying boxes by address and other explorer-like features.

Mining Configuration

For solo mining or pool mining setup:

ergo {
node {
mining = true
useExternalMiner = true
miningPubKeyHex = "your_public_key_hex"
}
}

Production Best Practices

Security Hardening

API Key Protection:

  • Generate strong, random API keys
  • Use SHA256 hashing for API key storage
  • Never commit API keys to version control
  • Rotate API keys regularly
  • Use different keys for different services

Wallet Security:

  • Store mnemonic seed phrases offline in multiple secure locations
  • Use strong wallet passwords (16+ characters)
  • Enable 2FA where supported
  • Never expose wallet API endpoints publicly
  • Regular backup of wallet data

Network Security:

  • Restrict P2P port access to necessary peers
  • Use firewall rules to limit API access
  • Enable HTTPS for API access
  • Monitor for suspicious connection patterns

Backup and Recovery

Blockchain Data Backup:

  1. Identify Critical Data:

    • Blockchain database: /home/ergo/.ergo/data
    • Wallet data: /home/ergo/.ergo/wallet
    • Configuration: application.conf
  2. Automated Backup Strategy:

    #!/bin/bash
    # Backup script for Ergo node
    BACKUP_DIR="/backup/ergo-$(date +%Y%m%d)"
    ERGO_DATA="/home/ergo/.ergo"
    # Create backup directory
    mkdir -p "$BACKUP_DIR"
    # Backup wallet data (critical)
    tar -czf "$BACKUP_DIR/wallet-backup.tar.gz" "$ERGO_DATA/wallet"
    # Backup configuration
    cp "$ERGO_DATA/application.conf" "$BACKUP_DIR/"
    # Optional: Backup recent blockchain data
    # (Full blockchain can be re-synced)
    tar -czf "$BACKUP_DIR/recent-blocks.tar.gz" \
    --exclude='*.dat' \
    "$ERGO_DATA/data/blocks" 2>/dev/null || true
    echo "Backup completed: $BACKUP_DIR"
  3. Store Backups Securely:

    • Encrypt sensitive backups
    • Store off-site or in cloud storage
    • Test restore procedures quarterly
    • Keep multiple backup versions

Wallet Recovery:

Terminal window
# Restore wallet from mnemonic
curl -X POST "http://example-app.klutch.sh:8000/wallet/restore" \
-H "Content-Type: application/json" \
-d '{
"pass": "your_password",
"mnemonic": "your twelve word seed phrase",
"mnemonicPass": ""
}'

Monitoring and Observability

Health Monitoring:

#!/bin/bash
# Health check script
NODE_URL="http://example-app.klutch.sh:8000"
# Check if node is responding
if ! curl -s "$NODE_URL/info" > /dev/null; then
echo "ERROR: Node not responding"
exit 1
fi
# Check sync status
SYNC_DATA=$(curl -s "$NODE_URL/info")
FULL_HEIGHT=$(echo $SYNC_DATA | jq -r '.fullHeight')
HEADERS_HEIGHT=$(echo $SYNC_DATA | jq -r '.headersHeight')
if [ "$FULL_HEIGHT" -lt "$((HEADERS_HEIGHT - 10))" ]; then
echo "WARNING: Node is out of sync"
echo "Full: $FULL_HEIGHT, Headers: $HEADERS_HEIGHT"
fi
# Check peer count
PEERS=$(echo $SYNC_DATA | jq -r '.peersCount')
if [ "$PEERS" -lt 5 ]; then
echo "WARNING: Low peer count: $PEERS"
fi
echo "Node healthy: $FULL_HEIGHT/$HEADERS_HEIGHT blocks, $PEERS peers"

Key Metrics to Monitor:

  • Block synchronization status
  • Peer connection count
  • Memory usage and heap size
  • Disk space availability
  • API response times
  • Wallet balance changes

Log Monitoring:

Access logs through Klutch.sh dashboard:

  1. Navigate to your app
  2. Click “Logs”
  3. Monitor for errors or warnings
  4. Set up alerts for critical issues

Performance Optimization

Memory Tuning:

Adjust Java heap size based on node mode:

Terminal window
# Full archival node
MAX_HEAP=8G
# Pruned node
MAX_HEAP=4G
# Light node
MAX_HEAP=2G

Database Optimization:

ergo {
cache {
# History cache size (number of recently used items)
history = 1000
# Indexes cache size
indexes = 10000
# Network cache size
network = 100
}
}

Network Optimization:

scorex {
network {
# Increase for better connectivity
maxConnections = 50
# Timeout settings
connectionTimeout = 1s
handshakeTimeout = 30s
# Delivery settings
deliveryTimeout = 2s
maxDeliveryChecks = 2
}
}

Scaling Considerations

Vertical Scaling:

  • Small Node: 2 CPU, 4GB RAM, 50GB storage
  • Medium Node: 4 CPU, 8GB RAM, 100GB storage
  • Large Node: 8 CPU, 16GB RAM, 200GB storage

Horizontal Scaling:

For high-availability setups:

  1. Deploy multiple nodes in different regions
  2. Use load balancer for API requests
  3. Share blockchain data via network file system
  4. Implement failover mechanisms

Troubleshooting

Node Won’t Sync

Check Peer Connections:

Terminal window
# Get connected peers
curl http://example-app.klutch.sh:8000/peers/connected | jq

Solutions:

  • Verify P2P port (9020) is accessible
  • Check firewall rules
  • Add more known peers to configuration
  • Verify sufficient disk space
  • Increase timeout settings

Out of Memory Errors

Check Java Heap Usage:

Terminal window
# Monitor in logs for OutOfMemoryError

Solutions:

  • Increase MAX_HEAP environment variable
  • Reduce cache sizes in configuration
  • Switch to pruned or digest mode
  • Upgrade compute resources

Slow API Responses

Check Node Status:

Terminal window
curl http://example-app.klutch.sh:8000/info | jq '.fullHeight, .headersHeight'

Solutions:

  • Wait for full synchronization
  • Enable extraIndex for faster queries
  • Increase database cache sizes
  • Use pruned mode to reduce storage I/O
  • Scale up CPU resources

Wallet Issues

Wallet Not Unlocking:

  • Verify correct password
  • Check wallet initialization status
  • Restore from mnemonic if corrupted

Missing Transactions:

Terminal window
# Rescan blockchain
curl -X POST "http://example-app.klutch.sh:8000/wallet/rescan" \
-H "api_key: your_api_key"

Database Corruption

Symptoms:

  • Node crashes on startup
  • Sync keeps rolling back
  • “Database corruption” errors in logs

Recovery:

  1. Stop the node

  2. Backup wallet data

  3. Clear blockchain data:

    Terminal window
    rm -rf /home/ergo/.ergo/data
  4. Restart node to re-sync

Additional Resources

Conclusion

Deploying an Ergo node on Klutch.sh provides you with direct access to the Ergo blockchain, complete transaction validation independence, and the ability to develop ErgoScript applications. Whether you’re running a full archival node for maximum data availability, a pruned node for balanced resources, or a light node for minimal footprint, Klutch.sh’s managed infrastructure, persistent storage, and flexible compute resources ensure your Ergo node remains synchronized, secure, and performant.

Start participating in the Ergo network by deploying your node on Klutch.sh today and join the community building contractual money for the future.