китаев.tech

Как работает подтверждение блока

Что значит confirmation в Ethereum: как блоки подтверждают транзакцию, как считать confirmations и почему приложения ждут несколько блоков.

Как работает подтверждение блока

Подтверждение блока — это новый блок, который появился поверх блока с вашей транзакцией.

Если транзакция попала в блок 100, а текущий блок 103, у транзакции 4 confirmation: сам блок 100 и три блока после него.


Что считается подтверждением

text
Блок 100: транзакция включена
Блок 101: 2 confirmations
Блок 102: 3 confirmations
Блок 103: 4 confirmations

Когда транзакция только попала в блок, она уже выполнена и имеет receipt. Но приложение может подождать несколько confirmations, чтобы снизить риск reorg.


Читаем confirmations через RPC

typescript
import { ethers } from "ethers";

const provider = new ethers.JsonRpcProvider("https://ethereum.publicnode.com");

const latestBlock = await provider.getBlock("latest");

if (!latestBlock || latestBlock.transactions.length === 0) {
  throw new Error("В последнем блоке нет транзакций");
}

const txHash = latestBlock.transactions[0];
const tx = await provider.getTransaction(txHash);
const receipt = await provider.getTransactionReceipt(txHash);
const currentBlockNumber = await provider.getBlockNumber();

if (!tx || !receipt) {
  throw new Error("Транзакция ещё не доступна через RPC");
}

const confirmations = currentBlockNumber - receipt.blockNumber + 1;

console.log("Hash:", tx.hash);
console.log("Included in block:", receipt.blockNumber);
console.log("Current block:", currentBlockNumber);
console.log("Confirmations:", confirmations);
console.log("Receipt confirmations:", await receipt.confirmations());
console.log("Status:", receipt.status === 1 ? "success" : "failed");

Этот код берёт транзакцию из свежего блока mainnet и показывает, сколько подтверждений у неё уже есть.


Как это работает

provider.getBlock("latest") — читает свежий блок.

latestBlock.transactions[0] — берёт hash первой транзакции из блока.

provider.getTransactionReceipt(txHash) — возвращает receipt: результат выполнения и номер блока, куда попала транзакция.

provider.getBlockNumber() — читает текущую высоту сети.

currentBlockNumber - receipt.blockNumber + 1 — считает confirmations. + 1 нужен, потому что блок с самой транзакцией тоже считается первым подтверждением.


Pending, confirmed и finalized

У транзакции есть несколько состояний:

СостояниеЧто значит
Pendingтранзакция в mempool, блока ещё нет
Confirmedтранзакция попала в блок и получила receipt
Finalizedблок стал финальным на уровне консенсуса Ethereum

Для UX часто достаточно 1 confirmation: пользователь видит, что транзакция выполнена.

Для депозитов, мостов и крупных переводов приложения обычно ждут больше confirmations или finalized-состояние.


Что такое reorg

Reorg — это ситуация, когда сеть на короткое время выбирает другую цепочку блоков.

text
Было:
100 → 101A → 102A

Стало:
100 → 101B → 102B → 103B

Если транзакция была в блоке 101A, но новый canonical chain использует 101B, транзакция может снова стать pending или попасть в другой блок.

Чем больше блоков построено поверх вашего блока, тем ниже риск reorg.


Сколько confirmations ждать

Для обычного интерфейса:

text
0 confirmations → показывать "ожидает включения"
1 confirmation  → показывать "выполнено"
2+ confirmations → считать результат устойчивее

Для финансовой логики не хардкодьте одно число для всех сетей. У Ethereum mainnet, L2 и sidechain разная модель финальности.


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

Считать pending-транзакцию выполненной → пока нет receipt, State сети не изменился.

Забывать про + 1 при ручном подсчёте → блок с транзакцией уже даёт первое confirmation.

Ждать одинаковое число confirmations на всех сетях → mainnet, L2 и мосты имеют разные правила финальности и разные риски.


Что дальше

Материалы китаev.tech публикуются в образовательных целях и не являются инвестиционной рекомендацией. Примеры кода и описания протоколов — для обучения; использование в продакшне на ваш собственный риск. Дисклеймер и политика конфиденциальности.