← Blog
10 min de lectura
|
24 oct 2026

Evento Transfer ERC-20: Estructura, Temas y Cómo Escucharlo

Cómo funciona el evento Transfer ERC-20: su firma, hash de tema, cómo decodificar logs, los problemas de eth_getLogs y cómo obtener alertas de depósitos sin ejecutar nodos.

Capítulos
C
Chaingateway Team
Expertos en blockchain

Abstract illustration of token transfer event structure

El evento ERC-20 Transfer es el registro que emite un contrato de token cada vez que se mueven tokens. Su firma es Transfer(address indexed from, address indexed to, uint256 value), y es la única forma fiable para una aplicación fuera de la cadena de saber que ha ocurrido un pago. Para capturarlo, filtra los registros por el hash del tema del evento, decodifica el remitente, el destinatario y la cantidad, y espera hasta que el bloque sea seguro para confiar en él. Esta guía recorre cada paso, las trampas que cuestan dinero real y cuándo tiene sentido dejar de sondear los registros usted mismo.

TL;DR

  • El estándar define Transfer(address indexed from, address indexed to, uint256 value). Debe dispararse en cada movimiento de tokens, incluidas las transferencias de valor cero.
  • Para filtrar registros, use el hash keccak256 de Transfer(address,address,uint256) como tema 0. Los temas 1 y 2 son las direcciones from y to rellenadas; la cantidad se encuentra en el campo data.
  • eth_getLogs en puntos de conexión públicos tiene límites y puede devolver resultados incompletos para rangos de bloques grandes sin error. Pagine, y use infraestructura dedicada para producción.
  • ERC-20 no tiene devolución de llamada al destinatario, por lo que escuchar fuera de la cadena no es opcional si acredita saldos de usuario.
  • Si prefiere no ejecutar indexadores de registros, un servicio de webhook puede enviar notificaciones de transferencia decodificadas a su backend.

Tabla de contenidos

Qué es realmente el evento Transfer

Un contrato inteligente puede emitir eventos, que son señales escritas en el recibo de la transacción como registros. No se almacenan en el estado del contrato, por lo que son baratos de escribir y baratos de leer, pero un contrato no puede leerlos después. Su audiencia es el mundo exterior: monederos, exploradores de bloques, indexadores y su backend. El propio tutorial de Ethereum sobre eventos los describe como señales que las dapps y cualquier cosa conectada a la API JSON-RPC pueden escuchar y actuar en consecuencia.

Event receipt separated from contract state

Para los tokens, la especificación ERC-20 define el evento así:

event Transfer(address indexed _from, address indexed _to, uint256 _value)

Las reglas que importan en la práctica:

  • DEBE emitirse cuando se transfieren tokens, y eso incluye transferencias de valor cero.
  • La función transfer debe dispararlo, y también transferFrom, la función que usa un gastador después de que se concede una asignación.
  • Se espera que la acuñación (minting) lo emita con la dirección from establecida en la dirección cero. La quema (burning) hace lo inverso, con la dirección cero como destinataria (muchas implementaciones siguen esta convención).

Ese último punto es una fuente común de errores. Un listener que solo vigile “transferencias a mi dirección” funcionará bien, pero uno que trate cada Transfer como un pago entre usuarios leerá mal las acuñaciones y quemas.

El balance del token es lo que cuenta en la cadena, y el evento es un informe sobre él. Si quiere el contexto sobre la interfaz completa, lo cubrimos en nuestra publicación sobre el estándar de token ERC-20.

Anatomía de un log Transfer

Cuando se emite el evento, el nodo almacena un log con tres partes: la dirección del contrato emisor, una lista de topics y un blob de datos. La indexación decide dónde cae cada argumento.

Campo del logContenido para un Transfer ERC-20
addressEl contrato del token que emitió el evento (por ejemplo, un contrato de stablecoin)
topics[0]Hash de la firma del evento
topics[1]Emisor (from), rellenado a la izquierda hasta 32 bytes
topics[2]Receptor (to), rellenado a la izquierda hasta 32 bytes
dataEl value, un entero sin signo de 32 bytes

Las dos direcciones están indexadas, por lo que son buscables a través del filtro de logs. El valor no está indexado, por lo que se almacena en el campo data, lo que mantiene bajos los costes en cadena y significa que no puede filtrar por cantidad a nivel de nodo. Si necesita “transferencias de más de 1.000 tokens”, los obtiene y filtra en su propio código.

El hash del topic 0

Para consultar a través de JSON-RPC necesita el hash keccak256 de la cadena de firma canónica Transfer(address,address,uint256). Sin espacios, sin nombres de parámetros, sin la palabra clave indexed. El resultado es:

0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

La documentación de eventos de ethers.js usa este mismo mecanismo: el topic 0 es el hash de la firma, y los topics 1 y 2 corresponden a las direcciones from y to indexadas, cada una rellenada a 32 bytes.

Dos detalles le ahorran tiempo de depuración:

  1. Los decimales son su responsabilidad. El value es un entero en bruto. Un token con 6 decimales y un valor de 2500000 son 2,5 tokens. Lea decimals() del contrato (o guárdelo en caché por token) antes de mostrar cantidades.
  2. Mismo hash, distintos estándares. ERC-721 usa el mismo nombre de evento y tipos de argumentos, por lo que su topic 0 es idéntico. La diferencia es que el ID del token está indexado, por lo que un log de transferencia de NFT lleva cuatro topics y un campo data vacío, mientras que una transferencia fungible lleva tres topics. Verifique la cantidad de topics antes de decodificar, o analizará movimientos de NFT como pagos de tokens. Nuestra publicación sobre el estándar ERC-721 cubre ese aspecto.

Lectura de transferencias con eth_getLogs

El enfoque clásico es una llamada JSON-RPC directa. Un filtro que encuentre todas las transferencias de un token hacia una cartera tiene este aspecto:

{
"method": "eth_getLogs",
"params": [{
"fromBlock": "0x10d4f00",
"toBlock": "0x10d4f64",
"address": "0xTokenContractAddress",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
null,
"0x000000000000000000000000YourDepositAddressWithoutThe0x"
]
}]
}

Un null en una posición de tema significa “cualquier valor”. Aquí aceptamos cualquier remitente y fijamos el destinatario. Observe que el destinatario se rellena con ceros hasta 32 bytes.

Si prefiere una biblioteca, un breve tutorial como este gist de web3.py para logs de transferencia ERC-20 muestra la misma llamada envuelta en Python. Para actualizaciones en vivo en lugar de historial, eth_subscribe con el tipo logs envía nuevas coincidencias a través de un WebSocket.

Dónde le falla eth_getLogs

Parece simple y funciona en un tutorial. La producción es diferente. El artículo de SQD sobre los límites de eth_getLogs señala que los proveedores de nodos estándar a menudo limitan el número de logs devueltos, y que consultar un rango grande de bloques puede producir datos incompletos sin ningún error. Su orientación: pagine las solicitudes y use nodos de archivo para datos históricos. El mismo artículo advierte que confiar en endpoints públicos para uso intensivo en producción no es fiable, debido a las limitaciones de los filtros bloom y las lagunas de índice que difieren de un nodo a otro.

Las reglas prácticas:

  • Consulte ventanas de bloques pequeñas y avance, en lugar de pedir un rango gigante de una sola vez.
  • Compare la cantidad de resultados con lo que espera. Una truncación silenciosa parece exactamente un día tranquilo.
  • Almacene el número del último bloque procesado, para que un reinicio reanude donde se detuvo en lugar de saltarse bloques.
  • Mantenga una superposición de unos pocos bloques en cada pasada y desduplique por hash de transacción más índice de log.

Confirmaciones, reorgs e idempotencia

Un log que aparece en el último bloque no es definitivo. La cadena puede reorganizarse, y un bloque que contenía su transferencia puede ser reemplazado por uno que no la tiene. Una canalización de depósitos sólida trata el evento como una reclamación, no como un hecho, hasta que se han construido suficientes bloques encima de él.

Una máquina de estados simple funciona bien:

  1. Visto. Se detecta el log. Regístrelo, muestre “pendiente” al usuario y no acredite nada.
  2. Confirmado. El bloque es más antiguo que su umbral elegido. Acredite el saldo una vez.
  3. Huérfano. El log desapareció tras una reorganización. Marque el registro como inválido y alerte a quien necesite saberlo.

El umbral es una decisión de negocio. Una compra pequeña tolera menos confirmaciones que un depósito grande elegible para retirada. Elija el umbral por cadena y por importe, y documéntelo.

Sea cual sea su elección, haga que la acreditación sea idempotente. La clave única para un log es el hash de la transacción más el índice del log, no solo el hash de la transacción, porque una transacción puede emitir varios eventos Transfer (un swap, por ejemplo, emite al menos dos). Si su manejador recibe el mismo evento dos veces, por un reintento o una segunda fuente, no debe hacer nada la segunda vez.

Por qué no puede confiar en que el destinatario se dé cuenta

Las transferencias ERC-20 son silenciosas desde el lado receptor. Una dirección de monedero no ejecuta código y un contrato receptor no recibe ninguna notificación. La página ERC-20 de ethereum.org señala que los tokens se pierden cuando se envían a contratos que no reconocen la transferencia entrante, porque el estándar no tiene una devolución de llamada nativa, y afirma que, a fecha de 20 de junio de 2024, se habían perdido más de 83.656.418 dólares en tokens ERC-20 de esta forma. Una mitigación común es una comprobación require en el token que bloquea el envío al propio contrato del token.

Dos conclusiones para los desarrolladores:

  • Si ejecuta un contrato que debe recibir tokens, necesita su propia contabilidad. Existen estándares como los hooks estilo ERC-1363 para esto, pero no puede asumir que el token del remitente los soporte.
  • Si ejecuta un backend, el registro (log) Transfer es su único disparador. Perder uno significa que un cliente pagó y usted nunca se enteró.

Existe una segunda brecha: el evento no lleva ninguna referencia de pago. Nada vincula una transferencia a la factura 4471. La mayoría de las empresas lo resuelven asignando a cada factura o usuario una dirección de depósito única. Una propuesta más reciente, ERC-7699, extendería ERC-20 con una referencia de transferencia para que un mensaje para el destinatario viaje con el pago, pero es una propuesta y los tokens populares actuales no la implementan.

Casos límite que rompen listeners ingenuos

Tokens de estilo nativo. En algunas cadenas, una stablecoin está integrada en el protocolo en lugar de ser un contrato normal. La documentación de Arc sobre detección de depósitos explica que los movimientos de USDC nativo allí emiten un registro Transfer ERC-20 estándar desde una dirección de sistema, por lo que los desarrolladores filtran por ese emisor en lugar de por el contrato del token individual. La lección es general: lea la documentación de depósitos de cada cadena antes de asumir que un filtro por dirección de contrato es suficiente.

Tokens con comisión por transferencia y rebasing. El importe en el evento puede diferir del cambio real en el saldo del receptor, o los saldos pueden cambiar sin ningún evento Transfer. Si acepta tokens desconocidos, concilie con balanceOf en lugar de confiar solo en el evento.

Transferencias de valor cero. El estándar exige que emitan el evento. Los atacantes usan esto para envenenamiento de direcciones, enviando transferencias de valor cero que colocan una dirección parecida en el historial de la víctima. Ignore los registros de valor cero en cualquier flujo de depósito.

Tokens suplantados (spoofed). Cualquiera puede desplegar un contrato que emita un evento Transfer con cualquier nombre de token. Filtre por direcciones de contrato que reconozca, no solo por el topic 0.

Cinco casos límite comunes de listeners ERC-20

Otras cadenas. La misma forma de evento aparece en redes compatibles con EVM como Polygon, BNB Chain (BEP-20) y Arbitrum. Los tokens TRC-20 de TRON siguen la misma idea con sus propias herramientas; consulte nuestra comparación de TRC10 y TRC20 para ver en qué se diferencian.

Construir o comprar: ejecutar su propio listener

Un listener casero es un buen proyecto y una opción justa cuando los datos de blockchain son su producto principal. Para la mayoría de los equipos que aceptan pagos, es una misión secundaria con una larga cola de mantenimiento. Usted es responsable del nodo o del contrato con el proveedor, el cursor de bloques, la gestión de reorganizaciones, los reintentos, la decodificación para cada token, y la misma pila de nuevo para cada cadena adicional.

Una forma aproximada de decidir:

PreguntaSi sí, inclínese por construirSi no, inclínese por una API
¿Son los datos on-chain su producto?SíNo
¿Necesita análisis de logs personalizados más allá de los pagos?SíNo
¿Tiene un ingeniero que se encargará del tiempo de actividad del nodo y la lógica de reorganizaciones?SíNo
¿Da soporte a varias cadenas desde el primer día?NoSí

Si cae en la columna de la derecha, una API gestionada que le envíe eventos decodificados elimina toda la capa de indexación.

Perspectiva: lo que vemos cuando los equipos construyen detección de depósitos

Construimos una API unificada para pagos con criptomonedas, así que vemos el mismo patrón repetidamente. Un equipo empieza con un bucle eth_getLogs para un token en una cadena. Funciona. Luego añaden una segunda cadena, un segundo estándar de token, un trabajo de reintentos y un parche para reorganizaciones, y la funcionalidad de pago se ha convertido silenciosamente en un proyecto de infraestructura.

Nuestra opinión es que el evento Transfer es la primitiva correcta pero el lugar equivocado para invertir su tiempo de ingeniería. Lo que su aplicación necesita es una afirmación clara: esta dirección recibió esta cantidad de este token en esta transacción. Por eso entregamos datos pre-decodificados en lugar de topics sin procesar, y por eso las notificaciones llegan a través de webhooks firmados con HMAC, para que su servidor pueda verificar que un mensaje realmente provino de nosotros antes de acreditar a nadie. También sostenemos que no debería necesitar ejecutar sus propios nodos ni hacer malabares con endpoints específicos de cada cadena para lograrlo.

El consejo que damos independientemente de las herramientas: use una dirección de depósito por pagador o factura, acredite de forma idempotente, espere confirmaciones que coincidan con el importe en juego y verifique la dirección del contrato del token. Esos cuatro hábitos previenen la mayoría de los incidentes de los que oímos hablar.

— Bitblade

Obtener notificaciones de transferencias sin ejecutar indexadores

Chaingateway ofrece a los desarrolladores una única API REST para carteras, transferencias de tokens y datos de transacciones decodificados en Ethereum, Bitcoin, Tron, Solana, Polyggon, BNB Chain y Arbitrum. Para este tema, la pieza relevante son los Chaingateway Webhooks: usted suscribe una dirección y, cuando una transferencia de token la afecta, una notificación en tiempo real llega a su endpoint con los datos ya decodificados, de modo que se salta el hashing y el padding de topics. Nuestra página de API de Ethereum muestra cómo enviar tokens ERC-20 sobre REST sin web3.js, y la guía de direcciones ERC-20 cubre el formato de dirección y la comprobación de saldos.

Los planes se publican en la página de precios: Plus son 49 € al mes, Pro 99 €, Premium 249 € y Enterprise 499 € al mes, con facturación anual a 490 €, 990 €, 2.490 € y 4.990 € respectivamente. El acceso a la Blockchain API comienza con una prueba gratuita.

Un gestor mínimo, paso a paso

Tanto si usa logs sin procesar como webhooks, la lógica del lado del servidor es la misma.

  1. Verifique la fuente. Para webhooks, compruebe la firma HMAC en el cuerpo de la solicitud sin procesar antes de analizarlo. Para su propio lector de logs, ya confía en su nodo.
  2. Compruebe el token. Compare la dirección del contrato con su lista de permitidos.
  3. Compruebe el destinatario. Busque la dirección to en su base de datos de direcciones de depósito. Ignore cualquier cosa desconocida.
  4. Elimine el ruido. Descarte transferencias de valor cero y acuñaciones o quemas que no le interesen.
  5. Elimine duplicados. Inserte el hash de la transacción y el índice del log bajo una restricción única. Si la inserción falla, deténgase.
  6. Convierta el importe. Divida el valor bruto por 10 elevado a la potencia de los decimales del token, usando tipos enteros o decimales, nunca punto flotante.
  7. Regístrelo como pendiente y luego confirmado. Abone solo después de que se supere su umbral de confirmación.
  8. Responda rápido. Acuse recibo de un webhook con un estado de éxito inmediatamente y realice el trabajo pesado en una cola.

Preguntas frecuentes

¿Cuál es el hash del tema del evento Transfer de ERC-20?

Es el hash keccak256 de Transfer(address,address,uint256), que es 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. Siempre se encuentra en el tema 0 del log. Los temas 1 y 2 contienen el remitente y el destinatario.

¿Por qué el valor no está indexado?

Los argumentos indexados se convierten en temas que los nodos pueden buscar, pero cada uno añade coste de log, y el estándar mantiene indexadas solo las dos direcciones. El valor va en el campo data, así que usted lo decodifica y filtra los importes en su propio código.

¿Cada movimiento de token emite un evento Transfer?

El estándar dice que debe hacerlo, incluidas las transferencias de valor cero. En la práctica, los contratos compatibles lo hacen, pero los tokens no estándar pueden comportarse de forma diferente, y algunas cadenas gestionan los activos nativos de manera especial. Trate el evento como la señal principal y concilie con balanceOf cuando el token sea desconocido.

¿Puedo confiar en eth_getLogs para depósitos en producción?

Solo con cuidado. Los proveedores pueden limitar los logs devueltos, y los rangos grandes pueden devolver datos incompletos sin error. Pagine en ventanas pequeñas, registre su último bloque procesado y use infraestructura dedicada o un servicio de notificaciones para cualquier cosa que maneje dinero real.

¿Cuántas confirmaciones debo esperar?

No hay un número universal. Depende de la cadena, el importe y su tolerancia al riesgo. Establezca un umbral por cadena y nivel de valor, y abone solo una vez, después de que se supere.

Fuentes

Recomendado

¿Listo para construirlo tú mismo? Obtenga su clave de API — prueba de 7 días, sin tarjeta — o consulte API Blockchain para la referencia completa de los endpoints.

C
Chaingateway Team
Expertos en blockchain

El equipo de Chaingateway se dedica a simplificar la integración blockchain para desarrolladores de todo el mundo.