Backend & Indexer Development Environment

Set up a complete development environment for the explorer backend and indexer.

This guide covers the setup required for contributing to the OpenScan.AI backend and indexer repositories — the services that fetch blocks, index chain data, and serve the REST API.


Architecture overview

The backend is Blockscout-derived and consists of:

  • Indexer — Elixir processes that fetch blocks, transactions, receipts, and internal transactions from a JSON-RPC endpoint and write them to PostgreSQL.
  • API server — serves the REST API v2 (/api/v2/...) from indexed data.
  • Frontend — a separate TypeScript/React application (see Frontend & Docs Setup).

Prerequisites

ToolVersionPurpose
Gitany recentSource control
Erlang/OTP26+Runtime for the backend
Elixir1.17+Backend language
PostgreSQL15+Indexed data storage
Docker24+Optional: containerized run
A JSON-RPC endpointany synced EVM nodeChain data source

For a local chain data source, any EVM archive or full node works — a synced XDC node, an Anvil/Hardhat devnet, or a public RPC endpoint for light testing.

Clone and configure

Terminal window
git clone https://github.com/OpenScanAI/blockscout.git
cd blockscout
cp .env.example .env

The essential environment variables:

Terminal window
# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/blockscout
# Chain connection
ETHEREUM_JSONRPC_HTTP_URL=http://localhost:8545
ETHEREUM_JSONRPC_TRACE_URL=http://localhost:8545
CHAIN_ID=50
# Instance identity
NETWORK="XDC Network"
SUBNETWORK="XDC Mainnet"
COIN=XDC
Terminal window
docker compose up --build

This starts PostgreSQL, runs migrations, and boots the indexer plus API server. The explorer UI is available at http://localhost:4000 once indexing begins.

Run from source

Terminal window
# Install dependencies
mix deps.get
# Create and migrate the database
mix ecto.create
mix ecto.migrate
# Start the indexer and API server
mix phx.server

Watch the logs for the fetcher supervision tree starting up. The first sync indexes from the configured starting block; point ETHEREUM_JSONRPC_HTTP_URL at a small devnet to keep initial sync fast.

Running tests

Terminal window
# Backend test suite
mix test
# With coverage
mix coveralls
# Lint and format checks
mix credo --strict
mix format --check-formatted

Run mix test before every commit in backend code. Fetcher changes should include tests covering the happy path plus at least one failure/retry scenario.

Common development tasks

Reset the local database

Terminal window
mix ecto.drop && mix ecto.create && mix ecto.migrate

Reindex a block range

Use the reindex tooling in apps/explorer or, for a local dev environment, drop and resync — it’s usually faster.

Debug a stuck fetcher

Fetcher logs include the module name (e.g. Indexer.Fetcher.Block). Filter logs by module, verify the RPC endpoint responds (curl -X POST $ETHEREUM_JSONRPC_HTTP_URL -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'), and check the fetcher’s retry backoff state.

Troubleshooting

  • Migrations fail on start — PostgreSQL version mismatch or a dirty local database; drop and recreate.
  • Indexer idle at block 0 — the RPC endpoint is unreachable or not synced; check eth_syncing on the node.
  • API returns stale data — the indexer is behind; check /api/v2/main-page/indexing-status.

Next steps