Blockchain Explorer on Website

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1 servicesAll 2065 services
Blockchain Explorer on Website
Complex
from 2 weeks to 3 months
FAQ

Our competencies:

Development stages

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1171
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    831
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    879
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    453

Building a Blockchain Explorer Website

A blockchain explorer is a web application for viewing transactions, blocks, addresses, and smart contracts on a blockchain. A full-featured explorer requires an archive node, an indexer, and a fast search backend.

System Components

Blockchain Node (archive)
    │
    ├── RPC/WebSocket (eth_getBlock, eth_getTransaction...)
    │
Indexer (custom or The Graph)
    │   Reads blocks → parses transactions → stores
    │
PostgreSQL + Redis (cache)
    │
REST API / GraphQL
    │
Frontend (Next.js)
    ├── Search (tx hash, address, block)
    ├── Block list
    ├── Transaction details
    ├── Address profile (balance + history)
    └── Smart contract call decoding

Indexer: Reading Blocks

import { createPublicClient, webSocket } from 'viem';
import { mainnet } from 'viem/chains';

const client = createPublicClient({
  chain: mainnet,
  transport: webSocket(process.env.ETH_WS_URL)
});

class BlockIndexer {
  async indexBlock(blockNumber: bigint): Promise<void> {
    const block = await client.getBlock({
      blockNumber,
      includeTransactions: true
    });

    await db.transaction(async (trx) => {
      // Save block
      await trx('blocks').insert({
        number: Number(block.number),
        hash: block.hash,
        parent_hash: block.parentHash,
        timestamp: new Date(Number(block.timestamp) * 1000),
        miner: block.miner,
        gas_used: block.gasUsed.toString(),
        gas_limit: block.gasLimit.toString(),
        transaction_count: block.transactions.length,
        base_fee_per_gas: block.baseFeePerGas?.toString() ?? null
      });

      // Save transactions
      for (const tx of block.transactions) {
        await trx('transactions').insert({
          hash: tx.hash,
          block_number: Number(tx.blockNumber),
          from_address: tx.from.toLowerCase(),
          to_address: tx.to?.toLowerCase() ?? null,
          value: tx.value.toString(),
          gas: tx.gas.toString(),
          gas_price: tx.gasPrice?.toString() ?? null,
          max_fee_per_gas: tx.maxFeePerGas?.toString() ?? null,
          input: tx.input,
          nonce: tx.nonce,
          transaction_index: tx.transactionIndex
        });

        // Update address stats
        await this.updateAddressStats(trx, tx.from.toLowerCase());
        if (tx.to) await this.updateAddressStats(trx, tx.to.toLowerCase());
      }
    });
  }

  // Real-time new blocks tracking
  async watchNewBlocks(): Promise<void> {
    const unwatch = client.watchBlocks({
      onBlock: async (block) => {
        await this.indexBlock(block.number);
      },
      onError: (error) => {
        logger.error('Block watch error', error);
      }
    });

    // Backfill missed blocks
    const latestIndexed = await this.getLatestIndexedBlock();
    const currentBlock = await client.getBlockNumber();

    for (let i = latestIndexed + 1n; i <= currentBlock; i++) {
      await this.indexBlock(i);
    }
  }
}

API: Search

app.get('/api/search', async (req, res) => {
  const query = req.query.q as string;

  if (!query) return res.status(400).json({ error: 'Query required' });

  // Determine search query type
  if (/^0x[0-9a-f]{64}$/i.test(query)) {
    // Transaction or block hash
    const tx = await db('transactions').where('hash', query.toLowerCase()).first();
    if (tx) return res.json({ type: 'transaction', data: tx });

    const block = await db('blocks').where('hash', query.toLowerCase()).first();
    if (block) return res.json({ type: 'block', data: block });

  } else if (/^0x[0-9a-f]{40}$/i.test(query)) {
    // Ethereum address
    return res.json({ type: 'address', address: query.toLowerCase() });

  } else if (/^\d+$/.test(query)) {
    // Block number
    const block = await db('blocks').where('number', parseInt(query)).first();
    if (block) return res.json({ type: 'block', data: block });
  }

  res.json({ type: 'not_found' });
});

Frontend: Decoding Input Data

import { decodeFunctionData } from 'viem';

async function decodeTransactionInput(
  input: string,
  contractAddress: string
): Promise<DecodedInput | null> {
  if (input === '0x') return null;

  // Load ABI from verified contracts (Etherscan API or own DB)
  const abi = await getContractAbi(contractAddress);
  if (!abi) return { raw: input };

  try {
    const decoded = decodeFunctionData({ abi, data: input as `0x${string}` });
    return {
      functionName: decoded.functionName,
      args: decoded.args,
      raw: input
    };
  } catch {
    return { raw: input };
  }
}

Ready-Made Indexers

Instead of building from scratch:

  • The Graph — GraphQL indexer, free self-hosted option
  • Ponder — TypeScript framework for indexers
  • Moralis — managed API with indexing
  • Alchemy / QuickNode — RPC with transformations and webhooks

Implementation Timeframe

  • MVP explorer (transactions, blocks, addresses) without indexer (via RPC) — 2–3 weeks
  • Full indexer with PostgreSQL + API + Frontend — 6–10 weeks
  • Explorer for custom EVM network — 2–3 months