Decodificador de logs de eventos de Ethereum

Convierte entradas de log en bruto (address, topics, data) en eventos y parámetros con nombre. Más de cuarenta eventos comunes se reconocen automáticamente; pega el ABI del contrato para cualquier otro. Todos los logs de un recibo se decodifican a la vez.

Funcionan las pestañas "Logs" de los exploradores, viem, ethers y envoltorios JSON-RPC; se decodifican todos los logs de un recibo.
Ejemplos:

Se calcula en tu navegador con JavaScript. Las direcciones nunca se suben ni se almacenan.

¿Qué es un log de eventos?

Un log de eventos es el registro que escribe un contrato EVM cuando ejecuta los opcodes LOG0–LOG4 (emit en Solidity). Cada entrada contiene la dirección del contrato emisor, hasta cuatro topics de 32 bytes y un campo data de longitud arbitraria. Decodificar un log consiste en hacer coincidir topics[0] con la firma de un evento, leer los parámetros indexed de los topics restantes y decodificar con ABI los parámetros no indexados a partir de data. Los exploradores lo hacen con el código fuente verificado; esta página lo hace solo a partir de la firma, para más de cuarenta eventos comunes, o a partir de cualquier ABI que pegues.

Cómo se codifica un log

CampoContenidoEjemplo (Transfer ERC-20)
addressEl contrato que emitió el evento0xdAC17F958D2ee523a2206206994597C13D831ec7 (USDT)
topics[0]keccak256 de la firma canónica0xddf252ad… = keccak256("Transfer(address,address,uint256)")
topics[1]Primer parámetro indexado, rellenado a la izquierda hasta 32 bytesdirección from
topics[2]Segundo parámetro indexadodirección to
dataCodificación ABI de todos los parámetros no indexadosvalue de 32 bytes

Los parámetros indexados de tipo estático (address, enteros, bool, bytes1–32) se almacenan directamente en el topic. Los parámetros indexados de tipo dinámico (string, bytes, arrays, structs) se sustituyen por el hash Keccak-256 de su codificación, como describe la sección de eventos de la especificación ABI de Solidity; el decodificador los marca como hasheados.

Ejemplo práctico: una transferencia de USDT

Pulsa "Transfer ERC-20" arriba. topics[0] coincide con la firma Transfer y, como hay exactamente tres topics, se elige el diseño ERC-20 (dos direcciones indexadas) frente al ERC-721 (tres indexados). topics[1] se decodifica como from = 0xd8dA6BF2…96045, topics[2] como to = 0x1111…1111, y la única palabra de data 0x17d7840 es value = 25000000, que con los seis decimales de USDT equivale a 25 USDT. El mismo mecanismo decodifica un Swap de Uniswap V2 (dos direcciones indexadas, cuatro importes en data) o un TransferBatch ERC-1155, cuyo campo data contiene dos arrays dinámicos con offsets y longitudes.

Eventos reconocidos sin ABI

La tabla siguiente se genera en la página a partir de la misma lista de firmas que usa el decodificador, por lo que cada valor de topics[0] es una autocomprobación de la implementación de Keccak. Cubre Transfer y Approval de ERC-20 y ERC-721, ApprovalForAll, TransferSingle, TransferBatch y URI de ERC-1155, Deposit y Withdrawal de WETH, Swap, Sync, Mint, Burn y PairCreated de Uniswap V2, Swap, Mint, Burn, Collect y PoolCreated de Uniswap V3, OwnershipTransferred, Upgraded, AdminChanged y BeaconUpgraded de EIP-1967, los eventos de Initializable, Pausable y AccessControl, Approval, Permit, NonceInvalidation y Lockdown de Permit2, Deposit y Withdraw de ERC-4626, y ExecutionSuccess, ExecutionFailure, SafeMultiSigTransaction, cambios de owner y threshold, SafeSetup y ProxyCreation de Safe.

Entradas aceptadas

Relacionado: calcula el hash de topic de cualquier firma con la calculadora de selectores y topics, decodifica el calldata de la transacción con el decodificador ABI o inspecciona una transacción en bruto con el decodificador de transacciones de Ethereum.

Preguntas frecuentes

¿Qué son topics y data en un log de Ethereum?

Un log tiene hasta cuatro topics de 32 bytes y un campo data de longitud variable. topics[0] es el hash Keccak-256 de la firma del evento (salvo que el evento sea anonymous); topics[1..3] contienen los parámetros indexed, uno por topic; todos los parámetros no indexados se codifican con ABI en data, en orden de declaración, exactamente igual que los argumentos de una función.

¿Por qué un string o bytes indexado muestra un hash?

La EVM no puede meter un valor dinámico en un topic de 32 bytes, así que Solidity almacena en su lugar el keccak256 del valor. El string original no puede recuperarse del log; solo puede compararse con un candidato hasheando ese candidato. Las direcciones, los enteros, bool y bytesN se almacenan completos y se decodifican con normalidad.

Transfer de ERC-20 y ERC-721 tienen el mismo topics[0]. ¿Cómo se distinguen?

Ambos tienen la firma Transfer(address,address,uint256), así que topics[0] es idéntico. ERC-721 indexa tokenId, lo que da cuatro topics y data vacío; ERC-20 solo indexa from y to, lo que da tres topics y un campo data de 32 bytes. El decodificador elige el diseño cuyo número de parámetros indexados coincide con el log.

¿Qué pasa si el evento no se reconoce?

El log se muestra en bruto con topics[0] resaltado. Pega el ABI del contrato (basta con los eventos) o una sola línea como event Bid(address indexed bidder, uint256 amount) en el cuadro de ABI y vuelve a decodificar. Bases de datos de firmas como 4byte.directory y openchain.xyz pueden ayudarte a identificar un hash de topic desconocido.

¿Cómo funcionan los eventos anonymous?

Un evento declarado anonymous no tiene topic de firma, así que todos sus topics son parámetros indexados y nada lo identifica on-chain. El decodificador solo puede cotejarlo con los eventos anonymous del ABI que proporciones, por número de topics, y lo indica en una nota.

¿Los importes se convierten a unidades del token?

Los enteros se muestran como decimales exactos. Para valores uint256, una pista muestra el valor dividido entre 1018 y 106, lo que cubre ETH, la mayoría de los ERC-20, USDC y USDT. Para otros decimales usa el conversor de decimales de tokens; el decodificador no conoce los decimales de cada token.

¿Se sube algo?

No. Los hashes de topic de la tabla integrada se calculan con Keccak-256 en tu navegador al cargar la página, y la decodificación se ejecuta localmente. La página no hace peticiones de red después de cargarse.