Декодер журналов событий Ethereum

Превращайте сырые записи логов (address, topics, data) в именованные события и параметры. Более сорока распространённых событий распознаются автоматически; для остальных вставьте ABI контракта. Все логи из receipt декодируются сразу.

Подходят вкладки «Logs» обозревателей, viem, ethers и обёртки JSON-RPC; декодируется каждый лог в receipt.
Примеры:

Вычисляется в вашем браузере на JavaScript. Адреса никогда не загружаются на сервер и не сохраняются.

Что такое журнал событий?

Журнал событий (лог) — это запись, которую EVM-контракт создаёт при выполнении опкодов LOG0–LOG4 (emit в Solidity). Каждая запись содержит адрес контракта, создавшего событие, до четырёх 32-байтовых topics и поле data произвольной длины. Декодировать лог — значит сопоставить topics[0] с сигнатурой события, прочитать indexed-параметры из остальных topics и ABI-декодировать неиндексированные параметры из data. Обозреватели делают это по верифицированному исходному коду; эта страница — только по сигнатуре для более чем сорока распространённых событий или по любому вставленному вами ABI.

Как кодируется лог

ПолеСодержимоеПример (ERC-20 Transfer)
addressКонтракт, создавший событие0xdAC17F958D2ee523a2206206994597C13D831ec7 (USDT)
topics[0]keccak256 канонической сигнатуры0xddf252ad… = keccak256("Transfer(address,address,uint256)")
topics[1]Первый индексированный параметр, дополненный слева до 32 байтадрес from
topics[2]Второй индексированный параметрадрес to
dataABI-кодирование всех неиндексированных параметров32-байтовое value

Индексированные параметры статического типа (address, целые числа, bool, bytes1–32) хранятся в топике напрямую. Индексированные параметры динамического типа (string, bytes, массивы, структуры) заменяются хешем Keccak-256 их кодирования, как описано в разделе о событиях спецификации Solidity ABI; декодер помечает их как хешированные.

Разбор примера: перевод USDT

Нажмите «ERC-20 Transfer» выше. topics[0] совпадает с сигнатурой Transfer, и поскольку topics ровно три, выбирается раскладка ERC-20 (два индексированных адреса), а не ERC-721 (три индексированных параметра). topics[1] декодируется в from = 0xd8dA6BF2…96045, topics[2] — в to = 0x1111…1111, а единственное слово data 0x17d7840 — это value = 25000000, что при шести десятичных знаках USDT составляет 25 USDT. Тот же механизм декодирует Uniswap V2 Swap (два индексированных адреса, четыре суммы в data) или ERC-1155 TransferBatch, поле data которого содержит два динамических массива со смещениями и длинами.

События, распознаваемые без ABI

Таблица ниже генерируется на странице из того же списка сигнатур, который использует декодер, поэтому каждое значение topics[0] служит самопроверкой реализации Keccak. Она охватывает Transfer и Approval для ERC-20 и ERC-721, ApprovalForAll, ERC-1155 TransferSingle, TransferBatch и URI, WETH Deposit и Withdrawal, Uniswap V2 Swap, Sync, Mint, Burn и PairCreated, Uniswap V3 Swap, Mint, Burn, Collect и PoolCreated, OwnershipTransferred, EIP-1967 Upgraded, AdminChanged и BeaconUpgraded, события Initializable, Pausable и AccessControl, Permit2 Approval, Permit, NonceInvalidation и Lockdown, ERC-4626 Deposit и Withdraw, а также Safe ExecutionSuccess, ExecutionFailure, SafeMultiSigTransaction, изменения владельцев и порога, SafeSetup и ProxyCreation.

Поддерживаемые входные данные

См. также: вычислите хеш топика по любой сигнатуре в калькуляторе селекторов и топиков, декодируйте calldata транзакции в ABI-декодере или изучите сырую транзакцию в декодере транзакций Ethereum.

Часто задаваемые вопросы

Что такое topics и data в логе Ethereum?

У лога до четырёх 32-байтовых topics и поле data переменной длины. topics[0] — хеш Keccak-256 сигнатуры события (если событие не anonymous); topics[1..3] содержат indexed-параметры, по одному на топик; все неиндексированные параметры ABI-кодируются в data в порядке объявления — точно так же, как аргументы функции.

Почему индексированные string или bytes отображаются как хеш?

EVM не может уместить динамическое значение в 32-байтовый топик, поэтому Solidity сохраняет вместо него keccak256 значения. Исходную строку из лога восстановить нельзя; её можно лишь сравнить с кандидатом, захешировав этого кандидата. Адреса, целые числа, bool и bytesN хранятся целиком и декодируются как обычно.

У ERC-20 и ERC-721 Transfer одинаковый topics[0]. Как их различить?

У обоих сигнатура Transfer(address,address,uint256), поэтому topics[0] идентичен. ERC-721 индексирует tokenId, что даёт четыре topics и пустое data; ERC-20 индексирует только from и to, что даёт три topics и 32-байтовое поле data. Декодер выбирает раскладку, у которой число индексированных параметров совпадает с логом.

Что если событие не распознано?

Лог показывается в сыром виде с выделенным topics[0]. Вставьте ABI контракта (достаточно только событий) или одну строку вроде event Bid(address indexed bidder, uint256 amount) в поле ABI и декодируйте снова. Определить неизвестный хеш топика помогут базы сигнатур, такие как 4byte.directory и openchain.xyz.

Как работают анонимные события?

У события, объявленного как anonymous, нет топика с сигнатурой, поэтому все его topics — индексированные параметры, и ничто не идентифицирует его в блокчейне. Декодер может сопоставить его только с анонимными событиями из предоставленного вами ABI по количеству topics и сообщает об этом в примечании.

Пересчитываются ли суммы в единицы токена?

Целые числа показываются как точные десятичные значения. Для значений uint256 подсказка показывает значение, делённое на 1018 и 106, что покрывает ETH, большинство ERC-20, USDC и USDT. Для других десятичных разрядов используйте конвертер десятичных знаков токенов; декодер не знает decimals каждого токена.

Что-нибудь загружается на сервер?

Нет. Хеши топиков для встроенной таблицы вычисляются с помощью Keccak-256 в вашем браузере при загрузке страницы, и декодирование выполняется локально. После загрузки страница не делает сетевых запросов.