Skip to main content
This guide covers running an Autheo node from scratch. Two deployment methods are provided: Method A — systemd (build from source) and Method B — Docker (official GHCR image).

1. Chain reference

PropertyValue
Binaryautheod
Cosmos chain IDautheo_2127-1 (mainnet)
EVM chain ID2127 (0x84f)
Native denomaauth
Denom decimals18 (1 THEO = 10^18 aauth)
Default home dir$HOME/.autheo
Key algorithmeth_secp256k1
Block time~5 seconds
Block max gas30000000
Min gas prices10000000000000aauth
Ports (single node defaults):
PortProtocolPurpose
26656TCPCometBFT P2P
26657TCPCometBFT RPC
9090TCPgRPC
1317TCPREST API
8545TCPEVM JSON-RPC
8546TCPEVM WebSocket

2. Infrastructure requirements

Size your server to meet the following minimums before proceeding. Under-provisioned nodes are more likely to miss blocks and get jailed.
ResourceMinimumRecommended
CPU8 vCPU16 vCPU
RAM32 GB64 GB
Storage1 TB NVMe SSD2 TB NVMe SSD
Network1 Gbps10 Gbps
OSUbuntu 22.04 LTSUbuntu 22.04 LTS

3. Method A: systemd

3.1 Prerequisites

# Ubuntu / Debian
sudo apt update && sudo apt install -y \
  git make gcc build-essential \
  jq curl wget

# Go (must match go.mod — verify exact version at https://go.dev/dl/)
GO_VERSION=1.25.0
wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.bashrc
source ~/.bashrc

go version

3.2 Build the binary

git clone https://github.com/autheo-blockchain/autheo-chain-core
cd autheo-chain-core

make build
Install to PATH:
sudo cp ./build/autheod /usr/local/bin/autheod
autheod --help

3.3 Join the network

All official configuration files are in the autheo-blockchain/networks repository.
# 1. Clone the networks repo
git clone https://github.com/autheo-blockchain/networks

# 2. Initialize the node
autheod init <moniker> \
  --chain-id $(cat networks/mainnet/chain-id) \
  --home $HOME/.autheo

# 3. Copy the official genesis
cp networks/mainnet/genesis.json $HOME/.autheo/config/genesis.json

# 4. Set persistent peers
CONFIG=$HOME/.autheo/config/config.toml
sed -i "s|^persistent_peers = .*|persistent_peers = \"$(cat networks/mainnet/persistent_peers.txt)\"|" $CONFIG

# 5. Set minimum gas prices
APP=$HOME/.autheo/config/app.toml
sed -i 's|^minimum-gas-prices = .*|minimum-gas-prices = "10000000000000aauth"|' $APP
Then choose a sync method from section 5.

3.4 Configure the node

$HOME/.autheo/config/config.toml
CONFIG=$HOME/.autheo/config/config.toml

# Expose RPC to all interfaces (default is 127.0.0.1)
sed -i 's|laddr = "tcp://127.0.0.1:26657"|laddr = "tcp://0.0.0.0:26657"|' $CONFIG
$HOME/.autheo/config/app.toml
APP=$HOME/.autheo/config/app.toml

# Enable REST API (disabled by default)
sed -i '/^\[api\]/,/^\[/{s/^enable = false/enable = true/}' $APP
sed -i 's|address = "tcp://localhost:1317"|address = "tcp://0.0.0.0:1317"|' $APP

# Expose EVM JSON-RPC (enabled by default, bound to 127.0.0.1)
sed -i 's|address = "127.0.0.1:8545"|address = "0.0.0.0:8545"|' $APP
sed -i 's|ws-address = "127.0.0.1:8546"|ws-address = "0.0.0.0:8546"|' $APP

# Add debug and txpool namespaces
sed -i 's|api = "eth,net,web3"|api = "eth,net,web3,debug,txpool"|' $APP

# Expose gRPC (default is localhost:9090)
sed -i 's|address = "localhost:9090"|address = "0.0.0.0:9090"|' $APP
$HOME/.autheo/config/client.toml
CLIENT=$HOME/.autheo/config/client.toml

sed -i 's|^keyring-backend = .*|keyring-backend = "file"|' $CLIENT

3.5 Start with systemd

Create /etc/systemd/system/autheod.service, adjusting User, WorkingDirectory, and ExecStart for your system user:
[Unit]
Description=Autheo Chain Node
After=network-online.target
Wants=network-online.target

[Service]
User=autheo
WorkingDirectory=/home/autheo
ExecStart=/usr/local/bin/autheod start --home /home/autheo/.autheo
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
StandardOutput=journal
StandardError=journal
SyslogIdentifier=autheod

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable autheod
sudo systemctl start autheod
sudo systemctl status autheod
sudo journalctl -u autheod -f

4. Method B: Docker

The official image is published at ghcr.io/autheo-blockchain/autheod. Available tags:
TagUse
latestCurrent mainnet release
testnetCurrent testnet release
X.Y.ZPinned mainnet release
X.Y.Z-testnetPinned testnet release
For production validators, pin to a specific release tag rather than latest so that container restarts do not pull an unexpected upgrade. Find release tags on the GHCR package page.

4.1 Pull the image

docker pull ghcr.io/autheo-blockchain/autheod:latest

4.2 Prepare the data directory

The node home inside the container is /root/.autheo. Mount a host directory to persist state across container restarts.
mkdir -p $HOME/.autheo
All autheod commands inside the container must use --home /root/.autheo. To run commands against a running container from the host, use docker exec autheo-node autheod <command> --home /root/.autheo.

4.3 Join the network

# 1. Clone the networks repo (on the host)
git clone https://github.com/autheo-blockchain/networks

# 2. Initialize the node
docker run --rm \
  -v $HOME/.autheo:/root/.autheo \
  ghcr.io/autheo-blockchain/autheod:latest \
  autheod init <moniker> --chain-id autheo_2127-1 --home /root/.autheo

# 3. Copy the official genesis
cp networks/mainnet/genesis.json $HOME/.autheo/config/genesis.json

# 4. Set persistent peers
CONFIG=$HOME/.autheo/config/config.toml
sed -i "s|^persistent_peers = .*|persistent_peers = \"$(cat networks/mainnet/persistent_peers.txt)\"|" $CONFIG

# 5. Set minimum gas prices
APP=$HOME/.autheo/config/app.toml
sed -i 's|^minimum-gas-prices = .*|minimum-gas-prices = "10000000000000aauth"|' $APP
Then apply the sync method of your choice from section 5 using the host-side config files.

4.4 Configure the node

Apply config changes directly to the host-side directory. Use the same sed commands from section 3.4 — they operate on $HOME/.autheo/config/ which is mounted into the container.

4.5 Run the container

docker run -d \
  --name autheo-node \
  --restart unless-stopped \
  -v $HOME/.autheo:/root/.autheo \
  -p 26656:26656 \
  -p 26657:26657 \
  -p 9090:9090 \
  -p 1317:1317 \
  -p 8545:8545 \
  -p 8546:8546 \
  ghcr.io/autheo-blockchain/autheod:latest \
  autheod start --home /root/.autheo
View logs:
docker logs -f autheo-node
Stop and restart:
docker stop autheo-node
docker start autheo-node

5. Sync methods

After completing the join and configure steps for your chosen method, select one of the following sync strategies. Downloads a recent snapshot from a live sentry and syncs only the remaining blocks.
TRUST_HEIGHT=$(curl -s https://sentry1.autheo.com/block | jq -r '.result.block.header.height')
TRUST_HASH=$(curl -s "https://sentry1.autheo.com/block?height=$TRUST_HEIGHT" | jq -r '.result.block_id.hash')

CONFIG=$HOME/.autheo/config/config.toml
sed -i '/^\[statesync\]/,/^\[/{s/^enable = false/enable = true/}' $CONFIG
sed -i "s|^rpc_servers = .*|rpc_servers = \"https://sentry1.autheo.com,https://sentry2.autheo.com,https://sentry3.autheo.com\"|" $CONFIG
sed -i "s|^trust_height = .*|trust_height = $TRUST_HEIGHT|" $CONFIG
sed -i "s|^trust_hash = .*|trust_hash = \"$TRUST_HASH\"|" $CONFIG
sed -i 's|^trust_period = .*|trust_period = "336h"|' $CONFIG
State sync does not retain historical data before the snapshot height. If you need a full archive node, use genesis sync instead.

Option B: Genesis sync

Replays every block from block 1. Required only for a full archive node.
The chain has had no governance upgrades since genesis — no additional setup is needed for current genesis sync.
If governance upgrades occur in the future, genesis sync will require cosmovisor to manage binary swaps at each upgrade height. Historical upgrade plan names, heights, and binaries will be listed in mainnet/upgrades.json in the networks repo, following this structure:
[
  {
    "plan_name": "v1.7",
    "height": 1000000,
    "binary_version": "v1.7.0",
    "binary_url": "https://github.com/autheo-blockchain/autheo-chain-core/releases/download/v1.7.0/autheod_linux_amd64"
  }
]
plan_name is the exact string used in MsgSoftwareUpgrade. For each entry, create a matching cosmovisor directory with the corresponding binary.
go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest

export DAEMON_NAME=autheod
export DAEMON_HOME=$HOME/.autheo

mkdir -p $DAEMON_HOME/cosmovisor/genesis/bin
cp <genesis-binary> $DAEMON_HOME/cosmovisor/genesis/bin/autheod

# For each upgrade in mainnet/upgrades.json:
#   mkdir -p $DAEMON_HOME/cosmovisor/upgrades/<plan_name>/bin
#   cp <binary> $DAEMON_HOME/cosmovisor/upgrades/<plan_name>/bin/autheod
# The directory name must exactly match the plan_name field.

6. Verify the node

Sync status — catching_up must be false when fully synced:
# systemd
autheod status --node http://localhost:26657 | jq '.sync_info'

# Docker
docker exec autheo-node autheod status --node http://localhost:26657 | jq '.sync_info'
EVM and REST checks — run from the host for both methods:
# EVM - result must be "0x84f" (2127)
curl -s -X POST http://localhost:8545 \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

# EVM - block number
curl -s -X POST http://localhost:8545 \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

# REST API
curl -s http://localhost:1317/cosmos/base/tendermint/v1beta1/blocks/latest | jq '.block.header.height'

7. Key management

This chain uses eth_secp256k1 keys. Create a new key:
# systemd
autheod keys add <key_name> \
  --keyring-backend file \
  --algo eth_secp256k1 \
  --home $HOME/.autheo

# Docker
docker exec -it autheo-node autheod keys add <key_name> \
  --keyring-backend file \
  --algo eth_secp256k1 \
  --home /root/.autheo
Keyring backends:
BackendStorageUse case
fileEncrypted file on diskRecommended for production — passphrase required on each use
osOS keychainmacOS Keychain / Linux Secret Service
testPlaintext on diskDevelopment only — never use in production
Show address:
# systemd
autheod keys show <key_name> -a \
  --keyring-backend file \
  --home $HOME/.autheo

# Docker
docker exec autheo-node autheod keys show <key_name> -a \
  --keyring-backend file \
  --home /root/.autheo
List keys:
# systemd
autheod keys list \
  --keyring-backend file \
  --home $HOME/.autheo

# Docker
docker exec autheo-node autheod keys list \
  --keyring-backend file \
  --home /root/.autheo
Show validator consensus public key:
# systemd
autheod tendermint show-validator --home $HOME/.autheo

# Docker
docker exec autheo-node autheod tendermint show-validator --home /root/.autheo

8. Create a validator

Requirements:
  • Node is fully synced (catching_up: false)
  • Sufficient aauth balance for self-delegation and fees
  • A Sovereign license owned by this account and bound to this validator address in BOUND status
The x/licensedstaking module enforces at the MsgCreateValidator level that a Sovereign license in BOUND status exists on the validator address. The transaction is rejected if this condition is not met. Step 1 — Verify your Sovereign license is BOUND:
# systemd
autheod query license licenses-by-owner <your_address> \
  --node http://localhost:26657 --output json

autheod query license license-by-validator <validator_address> \
  --node http://localhost:26657 --output json

# Docker
docker exec autheo-node autheod query license licenses-by-owner <your_address> \
  --node http://localhost:26657 --output json

docker exec autheo-node autheod query license license-by-validator <validator_address> \
  --node http://localhost:26657 --output json
If your Sovereign license is in ISSUED status (not yet bound), bind it first:
# systemd
autheod tx license bind <license_id> \
  --from <key_name> \
  --keyring-backend file \
  --chain-id autheo_2127-1 \
  --gas auto \
  --gas-adjustment 1.5 \
  --gas-prices 10000000000000aauth \
  --home $HOME/.autheo \
  --yes

# Docker
docker exec autheo-node autheod tx license bind <license_id> \
  --from <key_name> \
  --keyring-backend file \
  --chain-id autheo_2127-1 \
  --gas auto \
  --gas-adjustment 1.5 \
  --gas-prices 10000000000000aauth \
  --home /root/.autheo \
  --yes
Confirm the license is now BOUND before proceeding:
# systemd
autheod query license license <license_id> \
  --node http://localhost:26657 --output json

# Docker
docker exec autheo-node autheod query license license <license_id> \
  --node http://localhost:26657 --output json
Step 2 — Create the validator:
Do not submit create-validator more than once with the same consensus key. Double-signing results in permanent tombstoning — the validator cannot be recovered. Verify you have only one running instance before submitting.
# systemd
VALIDATOR_PUBKEY=$(autheod tendermint show-validator --home $HOME/.autheo)

autheod tx staking create-validator \
  --pubkey "$VALIDATOR_PUBKEY" \
  --value 500000000000000000000aauth \
  --description '{"moniker":"<your_moniker>"}' \
  --commission '{"rate":"100000000000000000","max_rate":"200000000000000000","max_change_rate":"10000000000000000"}' \
  --min-self-delegation "1" \
  --from <key_name> \
  --keyring-backend file \
  --chain-id autheo_2127-1 \
  --home $HOME/.autheo \
  --gas auto \
  --gas-adjustment 1.5 \
  --gas-prices 10000000000000aauth \
  --yes

# Docker
VALIDATOR_PUBKEY=$(docker exec autheo-node autheod tendermint show-validator --home /root/.autheo)

docker exec autheo-node autheod tx staking create-validator \
  --pubkey "$VALIDATOR_PUBKEY" \
  --value 500000000000000000000aauth \
  --description '{"moniker":"<your_moniker>"}' \
  --commission '{"rate":"100000000000000000","max_rate":"200000000000000000","max_change_rate":"10000000000000000"}' \
  --min-self-delegation "1" \
  --from <key_name> \
  --keyring-backend file \
  --chain-id autheo_2127-1 \
  --home /root/.autheo \
  --gas auto \
  --gas-adjustment 1.5 \
  --gas-prices 10000000000000aauth \
  --yes
The self-delegation inside create-validator triggers the BOUND→ACTIVE license transition automatically. Step 3 — Verify the validator and license are active:
# systemd
VALIDATOR_ADDR=$(autheod keys show <key_name> --bech val -a \
  --keyring-backend file \
  --home $HOME/.autheo)

autheod query staking validator $VALIDATOR_ADDR \
  --node http://localhost:26657 --output json

# License must now show ACTIVE
autheod query license license-by-validator $VALIDATOR_ADDR \
  --node http://localhost:26657 --output json

# Docker
VALIDATOR_ADDR=$(docker exec autheo-node autheod keys show <key_name> --bech val -a \
  --keyring-backend file \
  --home /root/.autheo)

docker exec autheo-node autheod query staking validator $VALIDATOR_ADDR \
  --node http://localhost:26657 --output json

# License must now show ACTIVE
docker exec autheo-node autheod query license license-by-validator $VALIDATOR_ADDR \
  --node http://localhost:26657 --output json

9. Troubleshooting

Cannot connect to EVM JSON-RPC

Confirm the JSON-RPC server is enabled and bound correctly in app.toml:
# Both methods — config is on the host-mounted directory
grep -A5 '\[json-rpc\]' $HOME/.autheo/config/app.toml

Node not producing blocks / stuck

systemd:
# Check peer count
curl -s http://localhost:26657/net_info | jq '.result.n_peers'

# Check sync status
autheod status --node http://localhost:26657 | jq '.sync_info.catching_up'

# Check logs
sudo journalctl -u autheod -n 100 --no-pager
Docker:
# Check peer count
curl -s http://localhost:26657/net_info | jq '.result.n_peers'

# Check sync status
docker exec autheo-node autheod status --node http://localhost:26657 | jq '.sync_info.catching_up'

# Check logs
docker logs --tail 100 autheo-node