Провайдеры и RPC: как фронт соединяется с сетью

Что такое провайдер, откуда брать RPC-узел и почему публичные ноды подводят в проде.

Провайдер — объект-обёртка над соединением с RPC-узлом блокчейна; через него фронт читает данные и отправляет транзакции.

Чтобы что-то прочитать из блокчейна, нужен узел, который держит состояние сети и отвечает на JSON-RPC-запросы. Поднимать свой узел дорого и сложно, поэтому используют готовые RPC-эндпоинты.

Откуда берётся RPC-узел

  • Нода кошелька. MetaMask имеет встроенный RPC. Если пользователь подключил кошелёк, можно ходить через него (window.ethereum). Бесплатно, но завязано на наличие кошелька.
  • Провайдер-сервис (Infura, Alchemy). Даёт стабильный RPC по API-ключу. Это стандарт для прода: высокие лимиты, аналитика, надёжность.
  • Публичная нода. Бесплатные открытые эндпоинты (например, из chainlist). Удобны для прототипа, но в проде ненадёжны: лимиты, отвалы, иногда устаревшие данные.

Создание провайдера в ethers.js

В ethers v6 есть готовые классы провайдеров. Для своего RPC берут JsonRpcProvider, для кошелька — BrowserProvider:

import { JsonRpcProvider, BrowserProvider } from "ethers";

// 1) Свой RPC (Alchemy/Infura) — для чтения, без кошелька
const rpc = new JsonRpcProvider("https://eth-mainnet.g.alchemy.com/v2/КЛЮЧ");

// 2) Через кошелёк пользователя (нужен для подписи)
const browser = new BrowserProvider(window.ethereum);

// Пример чтения: текущий номер блока
const n = await rpc.getBlockNumber();
console.log("block:", n);

Код помечен как нерабочий в песочнице: ему нужен реальный сетевой провайдер и/или window.ethereum, которых в учебном окружении нет.

Как работает под капотом

Любой вызов провайдера превращается в HTTP- или WebSocket-запрос с телом JSON-RPC. Например, getBlockNumber() отправляет такой запрос:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_blockNumber",
  "params": []
}

Нода отвечает {"result": "0x12a4b6"} — номер блока в hex. ethers.js разбирает hex в число и отдаёт вам. Все методы провайдера — это такие пары «метод JSON-RPC + декодирование ответа».

WebSocket против HTTP

HTTP-провайдер хорош для разовых запросов «вопрос-ответ». Но если нужно слушать события в реальном времени (подписка на логи, новые блоки), нужен постоянный канал — WebSocket-провайдер (WebSocketProvider). Подписки по HTTP эмулируются опросом (polling) и работают хуже.

Частые ошибки

  • Светить API-ключ Alchemy в публичном фронте. Ключ виден в браузере; ограничивайте его по домену/методам в дашборде провайдера.
  • Полагаться на одну публичную ноду в проде. Она отвалится в самый неподходящий момент; держите запасной RPC.
  • Использовать HTTP-провайдер для подписок на события. Для realtime берите WebSocket.

Итоги

  • Провайдер — обёртка над RPC-узлом; через него идут все обращения к сети.
  • Для прода берут Infura/Alchemy; публичные ноды — только для прототипов.
  • Каждый вызов провайдера — это JSON-RPC-запрос к ноде; для realtime нужен WebSocket.
Проверьте себя
1. Какой провайдер ethers v6 подойдёт для чтения через свой Alchemy-RPC без кошелька?
ABrowserProvider
BJsonRpcProvider
CWebSocketProvider обязательно
DSigner
2. Чем по сути является вызов метода провайдера, например getBlockNumber()?
ASQL-запросом к базе
BJSON-RPC-запросом к ноде
CТранзакцией с газом
DЧтением localStorage
3. Когда нужен WebSocketProvider вместо HTTP?
AДля разового чтения баланса
BДля подписи транзакции
CДля подписки на события в реальном времени
DДля деплоя контракта