Разработка системы отслеживания газа (gas tracker)

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Разработка системы отслеживания газа (gas tracker)
Средний
~3-5 дней
Часто задаваемые вопросы

Направления блокчейн-разработки

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1309
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1222
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    922
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1151
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    614
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    887

Разработка трекера стоимости газа (gas tracker)

Gas tracker — это не просто "показываем eth_gasPrice". Полезный инструмент показывает историческую динамику, предсказывает оптимальное время транзакции, разделяет EIP-1559 компоненты и даёт оценки по типам транзакций. Разберём что внутри у нормального gas tracker-а.

EIP-1559: как работает gas pricing на Ethereum

После EIP-1559 (лондонский хардфорк, август 2021) цена газа состоит из двух частей:

baseFeePerGas — базовая комиссия, сжигается. Определяется протоколом: если блок > 50% заполненности, base fee растёт на 12.5%, если < 50% — падает. Предсказуема на 1-2 блока вперёд.

maxPriorityFeePerGas (tip) — чаевые майнеру/валидатору. Рыночная часть — конкурируете за включение в блок.

Реальная стоимость транзакции: min(maxFeePerGas, baseFeePerGas + priorityFee) * gasUsed.

Для gas tracker это важно: нужно отслеживать оба компонента отдельно, не только итоговую цену.

Архитектура: сбор и хранение данных

Источники данных

eth_feeHistory — основной метод для исторических данных. Возвращает baseFee, gasUsedRatio и percentile-статистику priorityFee за указанный диапазон блоков:

import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'

const client = createPublicClient({ chain: mainnet, transport: http(RPC_URL) })

// Получаем данные за последние 100 блоков
// percentiles: [25, 50, 75] — slow/standard/fast
const feeHistory = await client.getFeeHistory({
  blockCount: 100,
  rewardPercentiles: [25, 50, 75, 95],
})
// feeHistory.baseFeePerGas: BigInt[] (на 1 больше — включает следующий блок)
// feeHistory.reward: BigInt[][] (matrix: block x percentile)
// feeHistory.gasUsedRatio: number[] (0..1)

eth_gasPrice — актуальная цена на moment запроса. Legacy метод, для EIP-1559 сетей возвращает baseFee + минимальный tip.

Mempool данные — pending транзакции. eth_getBlockByNumber("pending") или подписка на pending txs через WebSocket. Нужно для real-time анализа конкуренции.

Схема хранения

TimescaleDB (PostgreSQL extension) — оптимально для time-series gas данных:

CREATE TABLE gas_stats (
    time          TIMESTAMPTZ NOT NULL,
    block_number  BIGINT NOT NULL,
    base_fee_gwei NUMERIC(20, 9) NOT NULL,
    tip_slow      NUMERIC(20, 9),  -- 25th percentile
    tip_standard  NUMERIC(20, 9),  -- 50th percentile
    tip_fast      NUMERIC(20, 9),  -- 75th percentile
    tip_instant   NUMERIC(20, 9),  -- 95th percentile
    gas_used_ratio NUMERIC(5, 4),  -- 0..1, заполненность блока
    network       VARCHAR(50) NOT NULL DEFAULT 'ethereum'
);

SELECT create_hypertable('gas_stats', 'time');
-- Агрегаты по часам для исторических графиков
SELECT add_continuous_aggregate_policy('gas_stats_hourly', ...);

Retention policy: детальные данные по блокам — 7 дней, часовые агрегаты — 1 год, дневные агрегаты — бессрочно.

Коллектор данных

Коллектор запускается в фоне и пишет данные по каждому новому блоку:

async function collectGasData() {
  const client = createWsClient(WS_RPC_URL)

  // Подписка на новые блоки через WebSocket
  client.watchBlocks({
    onBlock: async (block) => {
      const baseFee = block.baseFeePerGas
        ? Number(block.baseFeePerGas) / 1e9
        : null

      // Получаем percentile статистику за этот блок
      const history = await client.getFeeHistory({
        blockCount: 1,
        blockNumber: block.number,
        rewardPercentiles: [25, 50, 75, 95],
      })

      const [slow, standard, fast, instant] = history.reward[0].map(
        (r) => Number(r) / 1e9
      )

      await db.query(
        `INSERT INTO gas_stats (time, block_number, base_fee_gwei, tip_slow, tip_standard, tip_fast, tip_instant, gas_used_ratio)
         VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
        [new Date(Number(block.timestamp) * 1000), block.number, baseFee, slow, standard, fast, instant, history.gasUsedRatio[0]]
      )
    },
    onError: (err) => handleCollectorError(err),
  })
}

Алгоритм предсказания газа

Простой вывод текущего baseFee недостаточен. Нужна оценка: "сколько поставить чтобы попасть в следующий блок с вероятностью X%?"

Следующий baseFee предсказуем точно:

function predictNextBaseFee(currentBaseFee: bigint, gasUsedRatio: number): bigint {
  // EIP-1559: baseFee изменяется пропорционально отклонению от 50% цели
  const targetRatio = 0.5
  const maxChangeDenominator = 8n // 12.5% max change
  const delta = gasUsedRatio - targetRatio
  const change = (currentBaseFee * BigInt(Math.round(delta * 1000))) / (maxChangeDenominator * 1000n)
  return currentBaseFee + change
}

Priority fee — рыночная, предсказать сложнее. Используем EMA (exponential moving average) последних N блоков по каждому percentile:

def calculate_priority_fee_estimate(
    recent_tips: list[float],  # последние 20 блоков, 50th percentile
    alpha: float = 0.3,        # вес новых данных
) -> float:
    ema = recent_tips[0]
    for tip in recent_tips[1:]:
        ema = alpha * tip + (1 - alpha) * ema
    return ema

Паттерны по времени суток. Gas существенно дешевле в UTC 02:00-08:00 (ночь Европы и утро Азии до открытия рынка). Если транзакция не срочная — показываем "оптимальное окно":

-- Средний газ по часу UTC за последние 30 дней
SELECT
    EXTRACT(HOUR FROM time) AS hour_utc,
    AVG(base_fee_gwei + tip_standard) AS avg_total_fee
FROM gas_stats
WHERE time > NOW() - INTERVAL '30 days'
GROUP BY hour_utc
ORDER BY avg_total_fee ASC;

API и фронтенд

REST endpoints для интеграции:

GET /api/gas/current          — текущие рекомендации {slow, standard, fast, instant}
GET /api/gas/history?period=24h — история с агрегацией
GET /api/gas/predict?blocks=5  — прогноз на N блоков
GET /api/gas/networks          — данные по нескольким сетям

Для реального времени — WebSocket subscription: клиент подписывается и получает обновление на каждый новый блок без polling.

Мультичейн поддержка — отдельный коллектор на каждую сеть. L2 (Arbitrum, Optimism, Base) имеют двухкомпонентный gas: L2 execution fee + L1 data fee. Для Optimism L1 data fee считается через precompile GasPriceOracle (0x420000000000000000000000000000000000000F).

Технологический стек

Компонент Выбор
Коллектор TypeScript + viem
База данных TimescaleDB (PostgreSQL)
API Fastify или Express
Кэш Redis (текущие рекомендации)
Фронтенд React + Recharts/Highcharts
Деплой Docker Compose

Разработка базовой версии (Ethereum mainnet, история + текущие рекомендации) — 5-8 дней. Мультичейн с предсказаниями и детальной аналитикой — 2-3 недели.