Por qué una llamada al contrato falla tras simular con éxito

2026-09-03

Por qué una llamada al contrato falla tras simular con éxito

Tu monedero muestra una vista previa del swap, indica cuánto vas a recibir y no informa de ningún problema. Firmas, y la transacción aterriza en la cadena como un fallo que aun así te cobra gas. La vista previa no te mintió. Respondió a una pregunta sobre un momento, y tu transacción se ejecutó en otro.

Por qué una llamada al contrato falla tras simular con éxito: puntos clave de un vistazo

Qué ejecuta realmente una simulación

Una vista previa del monedero es un ensayo en seco. Un nodo ejecuta tu llamada contra una copia del estado de la cadena, informa de lo que ocurriría y después descarta el resultado. La documentación para desarrolladores de Ethereum describe el método que hay detrás como uno que ejecuta una nueva llamada de mensaje de inmediato sin crear una transacción en la cadena de bloques, y describe el método de gas asociado como uno que devuelve una estimación mientras la transacción no será añadida a la cadena de bloques.

De esa descripción se siguen dos propiedades, y ambas importan más adelante. El ensayo en seco se ejecuta contra un bloque elegido, así que su respuesta queda clavada al estado en ese bloque. Y se ejecuta en solitario: entre la llamada y el resultado no se ejecuta nada más.

El estado contra el que simulaste no es el estado en el que aterrizas

Entre la vista previa y la ejecución, tu transacción tiene que viajar. Se firma, se difunde, se retiene en un mempool, un productor de bloques la selecciona y solo entonces se ejecuta bajo las reglas del bloque que la contiene. Cada paso de ese viaje lleva tiempo, y la cadena no se detiene mientras ocurre.

El código del contrato lee el estado en el momento de la ejecución, nunca en el momento de la simulación. Las reservas de un pool, la respuesta de un oráculo, un límite de gasto concedido, una entrada en una lista blanca, un indicador de pausa, un tope por dirección, una subasta ya terminada: cualquiera de estos valores puede tener un valor cuando corre la vista previa y otro cuando se construye el bloque. Un contrato que inspecciona ese valor y se detiene cuando la condición no se cumple se comporta de forma idéntica en ambos momentos. Lo que cambió fue la entrada.

Salida mínima y fecha límite: las comprobaciones que fallan a propósito

Una llamada de swap puede llevar dos protecciones dentro de la propia llamada. Una es un suelo sobre lo que debes recibir, derivado de tu tolerancia de slippage. La otra es una marca de tiempo tras la cual la llamada deja de ser válida. Ambas son argumentos que firmas, así que ambas quedan congeladas en los valores que calculó la vista previa.

Supón que la vista previa cotiza 10.000 USDC por los tokens que vendes y que tu tolerancia está fijada en 0,5 %. La llamada lleva entonces un suelo de 9.950 USDC, y el contrato recibe la instrucción de abandonar toda la interacción antes que entregar menos. Cuando el precio se mueve más allá de tu tolerancia mientras la transacción está en camino, la protección hace exactamente lo que le pediste. La fecha límite se comporta igual: una llamada que sigue sin confirmar pasada su propia marca de tiempo es rechazada a su llegada, aunque la misma llamada habría pasado unos minutos antes.

Este es el caso en el que el fallo es la protección funcionando. Una protección que nunca se dispara dejaría que la interacción se liquidara al precio al que el mercado hubiera derivado cuando se construyó el bloque.

Ordenación: la misma transacción en otro lugar

Un bloque es una secuencia, y la ordenación de transacciones decide qué interacción ve qué estado. Tu vista previa colocó la llamada al principio de una cola vacía. El bloque la coloca detrás de todo lo que el productor puso ahí, y esos vecinos pueden consumir la liquidez, el límite de gasto o el suministro restante con los que contaba tu llamada.

Una acuñación con tope duro lo muestra con claridad. Diez monederos pueden simular cada uno con éxito la última unidad disponible, porque cada vista previa corre contra un estado en el que esa unidad sigue sin reclamar. Uno de ellos aterriza primero y los otros nueve encuentran un contrato agotado. No hubo nada mal en las nueve vistas previas. Respondieron a una pregunta que tenía una respuesta antes de que el bloque existiera y otra después.

Gas: una estimación no es una reserva

Una estimación de gas se produce igual que la vista previa, ejecutando la llamada una vez y midiéndola. La misma documentación advierte de que la estimación puede ser significativamente mayor que la cantidad de gas realmente usada por la transacción, y la dirección contraria es la que duele: una estimación medida sobre un camino barato puede quedarse corta para el camino que la transacción acaba tomando.

Las ramificaciones de la ejecución son donde se abre esa brecha. Un swap enrutado por un pool en la vista previa puede enrutarse por dos en la ejecución; la primera escritura en una posición de almacenamiento cuesta más que una escritura posterior en la misma posición; un bucle que tocó tres posiciones puede tocar nueve. Si el límite que firmaste se agota a mitad de la ejecución, el trabajo se deshace y el gas se consume igualmente, que es la misma aritmética que se aplica a cualquier transacción fallida. Dejar holgura por encima de la estimación no sube la comisión cuando esa holgura queda sin usar, porque cómo se fija el precio del gas separa la cantidad de trabajo del precio por unidad de trabajo.

Cuando la simulación no simulaba la transacción que enviaste

A veces la vista previa y la ejecución ni siquiera son la misma llamada. Una simulación se realiza contra un punto de acceso en una red, así que un monedero apuntando a otra cadena o a un nodo con estado desactualizado responde sobre un mundo distinto de aquel al que se difunde tu firma.

Tu propia cola de pendientes es una segunda fuente de este desajuste. Las transacciones de una cuenta se ejecutan en orden de nonce, así que una llamada pendiente anterior del mismo monedero corre primero y puede cambiar el estado del que depende una llamada posterior. Cuando esa llamada anterior es una aprobación sin confirmar, la interacción que espera detrás puede simularse contra el límite que esperas y ejecutarse contra el límite que realmente tienes.

Lo que mostró la vista previa Qué cambió al llegar la ejecución Dónde mirar
Un importe de salida cotizado Se movieron las reservas o la respuesta del oráculo El argumento de salida mínima en la llamada firmada
Una llamada válida La marca de tiempo firmada ya venció El argumento de fecha límite y el tiempo pendiente
Suministro o liquidez disponibles Otra transacción del bloque lo tomó antes La posición de tu transacción dentro de su bloque
Una estimación de gas La ejecución tomó una rama más larga El gas usado frente al límite de gas en el recibo
Un ensayo en seco limpio El monedero estaba en otra red u otro nodo El identificador de cadena y el punto de acceso al firmar

Qué aspecto tiene el fallo después

Una interacción que se detiene así queda registrada. Ocupa una posición en un bloque, consume gas y su recibo lleva un campo de estado: EIP-658 sustituyó la raíz de estado intermedia del recibo por un código de estado en el que cero indica fallo y uno indica éxito. Los exploradores convierten ese campo en la etiqueta revertida.

La etiqueta nombra el resultado y no la causa. Algunos contratos adjuntan una cadena de motivo al detenerse, y un explorador o una traza pueden mostrarla; otros se detienen sin adjuntar nada. Leer la transacción fallida junto a los argumentos que realmente firmaste es lo que convierte un código de estado en un diagnóstico, porque esos argumentos son la parte de la historia que el recibo no puede reconstruir por ti.

Qué reduce de verdad la tasa de fallos

Acorta la distancia. Una vista previa tomada un instante antes de firmar describe un estado más cercano al que tendrá el bloque, y una transacción que confirma rápido tiene menos tiempo para ser adelantada.

Dimensiona las protecciones según el activo y no según la costumbre. Un suelo lo bastante estrecho como para rechazar un minuto normal de movimiento en un mercado delgado detendrá tus interacciones una y otra vez, mientras que un suelo lo bastante amplio como para aceptar cualquier cosa renuncia a la protección para la que lo fijaste. El mismo criterio se aplica a la fecha límite, que debe ser lo bastante larga como para sobrevivir a un periodo de congestión.

Trata un fallo repetido como información. Cuando la misma interacción se detiene varias veces con los mismos argumentos, el contrato está informando de una condición que ahora mismo no se puede satisfacer, y reenviar la misma llamada gasta gas para recibir la misma respuesta.

En resumen

Una simulación responde a qué ocurriría si esta llamada corriera ahora, en solitario, contra este bloque. Una ejecución en cadena responde a qué ocurrió cuando la llamada corrió después, entre otras transacciones, contra otro bloque. Un fallo tras una vista previa limpia es la distancia entre esas dos preguntas, y las protecciones que firmaste son lo que convierte esa distancia en una parada en lugar de en una mala ejecución. Revisa los argumentos de la llamada firmada, la posición de la transacción dentro de su bloque y el gas usado frente al límite de gas, y el motivo estará en uno de los tres. Para seguir aprendiendo los fundamentos, sigue más contenidos de Bitbase Academy.

Lecturas relacionadas

Otros artículos de Bitbase sobre este tema:

- Cómo cambiar de endpoint RPC de forma segura

- Comisión máxima de transacción superada: qué significa ese aviso de la billetera

- Límite de solicitudes RPC excedido y cómo evitarlo

- FIFO y LIFO en la base de coste de las criptomonedas

- Prima memética: por qué los memes mueven los precios

Aviso legal: Este artículo es contenido educativo de Bitbase Academy y se ofrece solo con fines informativos. No constituye asesoramiento de inversión, negociación, fiscal ni financiero. Los criptoactivos son volátiles; evalúa tu propio riesgo. Redactado en septiembre de 2026; consulta la información oficial más reciente.

Fuentes

[1] Documentación para desarrolladores de Ethereum.org, JSON-RPC API (eth_call, eth_estimateGas) ethereum.org

[2] Ethereum Improvement Proposals, EIP-658: Embedding transaction status code in receipts eips.ethereum.org

[3] Documentación para desarrolladores de Ethereum.org, «Transacciones» (Transactions) ethereum.org

Artículos relacionados

Más