Estimación de gas ERC-4337 para L2 y agregadores de firmas
Autores: Dan Coombs, David Philipson
En ERC-4337 Gas Estimation analizamos cómo funciona el gas en ERC-4337 y nuestro método para la estimación de gas. En la parte 2, Dummy Signatures and Gas Token Transfers, descubrimos que estimar el gas no siempre es sencillo, y que debemos tener en cuenta casos límite. Este artículo profundiza en algunos casos límite adicionales que encontramos.
El problema de las L2
Parte de la definición de un Ethereum Layer 2 rollup es: "permite que la capa 1 se encargue de la seguridad, la disponibilidad de datos y la descentralización, mientras que las capas 2 se encargan del escalado."
Para lograr esto, las L2 "agrupan" muchas transacciones en un solo lote y luego las publican en la blockchain de capa 1. Este costo de transacción no es gratuito, ya que las L2 deben pagar los costos de calldata generados al publicar un lote grande de datos en la cadena L1.
Las L2 necesitan una forma de cobrar a sus usuarios estos costos de calldata en L1. Los frameworks de rollup logran esto de diferentes maneras.
Este artículo se enfoca en los dos rollups EVM más grandes: Arbitrum y Optimism.
¿Cómo calcula Arbitrum el costo para cubrir las comisiones de gas en L1?
En Arbitrum, el cargo de gas en L2 para cubrir el costo de gas en L1 se calcula usando la siguiente fórmula, donde el tamaño de los datos es su tamaño en bytes después de la compresión Brotli:
💡 Costo L1 (L1C) = precio L1 por byte de datos (L1P) * tamaño de los datos a publicar en bytes (L1S)
💡 Gas (G) = Costo L1 (L1C) / Precio de gas L2 (P)
Este gas se cobra antes de que comience la ejecución de la transacción y cuenta para el gasLimit de la transacción. Por lo tanto, debe tenerse en cuenta durante la estimación de gas de la transacción.
¿Cómo calcula Optimism el costo para cubrir las comisiones de gas en L1?
En Optimism, el costo de gas en L1 se calcula de manera similar, donde el tamaño en bytes después de la compresión se multiplica por una comisión de L1. En lugar de traducir este valor a gas de L2 como hace Arbitrum, Optimism deduce el ETH requerido directamente de la cuenta del emisor.
Los emisores no necesitan tener en cuenta este valor durante la estimación de gas, pero no tienen la posibilidad de establecer un límite en su gasto. Optimism se encarga de asegurar que esta comisión no tenga picos.
¿Cómo puede un bundler en las L2 cobrar por las comisiones de L1?
En ambos casos, a un bundler que envía una transacción de bundle en una L2 se le cobra por las comisiones de L1. El bundler necesita una forma de cobrar a las user operations agrupadas por esta comisión aumentando el gas de L2.
El impacto efectivo en el gas de L2 se puede determinar mediante:
L2\_gas = L1\_gas \* L1\_fee / L2\_fee
verificationGasLimit y callGasLimit son medidos por el entry point y, por lo tanto, no pueden ser usados por los bundlers para cobrar por este gas adicional. Los bundlers deben recurrir a otros métodos.
Intento 1: establecer una priority fee más alta
Exigir un maxPriorityFeePerGas más alto podría permitir al bundler recuperar estas comisiones perdidas.
El cálculo se vería así:
- Estimar la comisión de L1 y convertirla en gas de L2 a. Suponer un bundle de tamaño 1 user operation y estimar el gas usando métodos provistos por la red, típicamente expuestos como llamadas especiales a contratos. b. Esto requiere asumir tanto una base fee de L1 como una base fee de L2 para convertir la comisión en valores de gas de L2.
- Estimar
verificationGasLimita. Dado que este límite de gas está bajo reglas de simulación estrictas, es muy probable que el valor estimado sea muy cercano al valor real, a diferencia decallGasLimit. - Establecer
maxPriorityFeePerGasBuffer=L1\_fee / verificationGasLimit - Sumar ese margen a cualquier priority fee requerida
Esto podría funcionar, pero tiene una UX terrible.
Para protegerse, el bundler debe asumir que la cantidad de call gas usado será 0 y cobrar al usuario como si la verification gas fuera el único componente. El usuario entonces pagará de más por el componente de margen de priority fee multiplicado por cualquier call gas usado. Esto no es bueno para el usuario.
Intento 2: manipular preVerificationGas
Eso deja a preVerificationGas como el único campo razonable para manipular. Esto encaja bien con la definición dada anteriormente de que preVerificationGas es "el campo de gas usado para capturar cualquier uso de gas que el entry point no puede medir". Dado que este es gas que el entry point no mide, esperaríamos poder usar este campo para cobrar al usuario.
El cálculo se vería así:
- Estimar la comisión de L1 y convertirla en gas de L2, establecido como
preVerificationGas. a. Suponer un bundle de tamaño 1 user operation y estimar el gas usando métodos provistos por la red, típicamente expuestos como llamadas especiales a contratos. b. Esto requiere asumir tanto una base fee de L1 como una base fee de L2 para convertir la comisión en valores de gas de L2. - Calcular el gas no medido de L2 y sumarlo al valor calculado arriba.
a. Este es el mismo método descrito en nuestra sección de cálculo de PreVerificationGas para un cálculo normal de
preVerificationGas. - Durante
eth\_sendUserOperationtambién ejecutar (1) y (2), y rechazar cualquier operación que no tenga unpreVerificationGassuficientemente alto como parte de la etapa de "pre-check". - Durante el bundling, ejecutar (1) y (2) nuevamente justo antes del envío.
a. Rechazar cualquier operación que no tenga un
preVerificationGassuficientemente alto.
Si bien este mecanismo funciona, tiene un problema de UX muy significativo.
Durante (2) el bundler debe asumir valores de base fee de L1 y L2 para realizar el cálculo de gas. Debido a que las base fees son dinámicas, si entre el paso de estimación de gas y el paso de envío/bundling la proporción de L1\_fee / L2\_fee aumenta, se requerirá un preVerificationGas más alto, y las user operations calculadas con una proporción menor serán rechazadas.
Lo mejor que el usuario puede hacer para mejorar esto es asumir que la proporción aumentará entre la estimación y el bundling y proveer un margen adicional en su preVerificationGas para mejorar sus posibilidades.
Dado que preVerificationGas siempre se cobra en su totalidad (es decir, no es un campo límite), el usuario está obligado a pagar por este margen adicional sin importar lo que ocurra con el precio. El usuario se ve forzado a elegir entre potencialmente pagar de más o que sus operaciones sean rechazadas.
💡 Rundler implementa el cálculo de preVerificationGas descrito arriba. Recomendamos que los usuarios de estas L2 agreguen un margen del 25% sobre el preVerificationGas retornado por eth\_estimateUserOperationGas para mejorar las posibilidades de que la operación no sea rechazada.
Caso límite de Optimism
Las base fees de Optimism son increíblemente bajas, a menudo muy por debajo de 100 wei (sí, wei). El preVerificationGas requerido para cobrar por la comisión de gas de L1 está inversamente relacionado con la comisión de gas de L2, lo que requiere que preVerificationGas sea extremadamente alto (en los millones).
La priority fee de Optimism suele ser órdenes de magnitud más alta que su base fee. Por lo tanto, un usuario debe ser muy cuidadoso de no enviar una priority fee proporcional a la priority fee de la red, ya que el entry point requiere el pago por preVerificationGas \(very high\) \* priority fee \(normal\) , causando un pago excesivo enorme. Por esta razón, Rundler requiere que la priority fee sea un porcentaje estático de la base fee para incentivar el bundling en Optimism.
El problema del signature aggregator
La agregación de firmas es una característica muy comentada de ERC-4337 por su capacidad de:
- Reducir los costos de calldata en las L2 mediante la compresión de firmas, lo que genera ahorros significativos.
- Amortizar el costo de gas de una verificación de validación agregada a través de un bundle de operaciones. a. Esta verificación de validación podría ser tan simple como una firma BLS, o tan compleja como una prueba ZK agregada.
En la versión actual del entry point, la llamada a la función validate del signature aggregator no está medida. Esto significa que el bundler necesita encontrar una forma de cobrar a las user operations agregadas por este gas, de manera similar al problema de las L2 mencionado antes.
Al igual que en el problema de las L2, la única forma razonable de hacer esto es aumentar preVerificationGas.
Una forma de hacerlo es:
- El bundler asume un tamaño de bundle de
target - El bundler llama a
validateUserOpen cada operación que recibe antes de la estimación para extraer una dirección de aggregator si se usa una. - Cuando se recibe una user operation agregada, el bundler necesita estimar la cantidad de gas usado por el signature aggregator, por operación, en ese tamaño de bundle objetivo.
a. Una forma sería replicar la user operation recibida
targetveces en un bundle y luego usareth\_estimateGasenaggregator.validateSignaturesb. Otra forma sería mantener una lista blanca de signature aggregators con mediciones de gas pre-cargadas (con un valor estático y un valor dinámico por operación). - Sumar el gas estimado al cálculo de
preVerificationGasdescrito arriba y retornar ese valor.
Hay algunos problemas con este enfoque:
- El bundler está tomando un riesgo al asumir un tamaño de bundle de
target. Ya sea que: a. El bundler espera hasta poder efectivamente agrupar el número de operaciones objetivo, perjudicando la UX mediante latencia b. El bundler agrupa menos del objetivo, y asume el costo - Los usuarios no pueden "ofertar" más o menos dependiendo de qué tan rápido quieren ser incluidos.
a. En un enfoque basado en límites, si un usuario quiere asegurar una inclusión rápida, puede sobreestimar el costo. Si el costo termina siendo menor, no se le cobra de más. En este enfoque, debido al
preVerificationGasestático, los usuarios siempre deben pagar toda su oferta. - En la red P2P, los bundlers pueden tener diferentes tamaños de bundle objetivo.
a. Esto significa que el bundler usado para la estimación puede sobreestimar/subestimar el
preVerificationGasrequerido por otro bundler en el mempool. b. Estas suposiciones off-chain perjudican la interoperabilidad del mempool.
Rundler actualmente no tiene soporte para signature aggregators debido a estas complicaciones. Es probable que agreguemos soporte para el método descrito arriba y asumamos un tamaño de bundle (pequeño, comenzando en 1), lo que hará que el uso de signature aggregators sea muy costoso.
Posibles cambios al entry point
Los problemas descritos arriba se deben a la falta de medición en el contrato entry point para el uso de gas significativo por parte de la user operation. Depender de preVerificationGas para cobrar por este uso de gas tiene el problema significativo de UX de requerir que los usuarios paguen más de lo que realmente usan para aumentar las posibilidades de que su UO se incluya onchain rápidamente.
Una solución a estos problemas podría ser modificar el contrato entry point para medir este uso adicional de gas y atribuirlo a campos de gas basados en límites.
Medición de gas de calldata L2-L1
💡 Este es un esbozo muy general de una solución a un problema difícil. ¡Nos encantaría escuchar ideas de la comunidad!
El costo de gas de calldata en L1 puede medirse onchain y a las user operations se les puede cobrar únicamente por el costo exacto en el que incurren, y no por el margen adicional. Se debería usar un campo basado en límites.
Una posible solución es introducir un nuevo campo, daCallDataGasLimit (da por Data Availability, nombre provisional). Este campo sería nativo de una versión L2+ del entry point y se usaría en cadenas donde el calldata de la transacción se publica en un sistema diferente y, por lo tanto, debe cobrarse de una manera separada.
La lógica del entry point sería la siguiente:
- Al momento del deployment, el entry point se asocia con un contrato auxiliar
daGasMeterque tiene una única funciónmeasureUserOperationDaGas\(UserOperation userOp\)a. Esta función toma una user operation y mide exactamente cuánto gas de DA se usó. b. Por ejemplo, en Arbitrum el medidor puede hacer una llamada agasEstimateL1Componentcon una user operation en memoria para determinar casi exactamente cuánto gas de L1 usó (no puede tener en cuenta la compresión adicional debido a un bundle con múltiples ops). - El entry point llamará a esta función para cada user operation antes de la validación y podrá atribuir este gas al
daCalldataGasLimit. - Para evitar reverts, en lugar de revertir si el gas de DA usado es mayor que el
daCalldataGasLimit, el entry point simplemente limitará ahí y el bundler queda pagando por cualquier gas que exceda este límite. Esto puede tenerse en cuenta off-chain por los bundlers asegurándose de que cualquier operación agrupada tenga un margen suficientemente alto en su campo límite antes del bundling.
Hay algunas desventajas bastante significativas en este enfoque:
- Los contratos entry point en diferentes cadenas tendrán diferentes direcciones.
- Utilización de gas durante la medición. a. Esto es menos un problema ya que en las L2+ el costo de gas de ejecución suele ser mucho menor que el costo de gas de datos.
Medición de gas del signature aggregator
El contrato entry point se puede modificar para medir la cantidad de gas usado durante su llamada a aggregator.validateSignatures, dividir eso entre la cantidad de user operations agregadas, y atribuir el uso de gas de manera uniforme deduciéndolo de verificationGasLimit.
Cada signature aggregator en la lista blanca debería estar asociado con un valor estático, el costo base para validar la firma agregada, y un valor dinámico, el aumento de costo por operación agregada. Por ejemplo, un signature aggregator BLS podría tener como valor estático el costo único de verificación de firma y como valor dinámico el costo de operaciones de hashing por op. Los bundlers pueden aumentar verificationGasLimit durante eth\_estimateUserOperationGas mediante el valor estático dividido entre un tamaño de bundle objetivo más el valor dinámico.
¿Cómo establecemos el tamaño de bundle objetivo?
Una posible solución aquí es complementar los argumentos de eth\_estimateUserOperationGas con un minimumBundleSize correspondiente al tamaño de bundle más pequeño (y por lo tanto de mayor gas) en el que el usuario quiere ser incluido. Los usuarios dispuestos a pagar más pueden reducir su tamaño mínimo de bundle y mejorar su tiempo de inclusión.
Los bundlers entonces necesitan lógica para asegurarse de incluir una UO solo en un bundle que sea al menos tan grande como el tamaño mínimo de bundle de esa UO. Este tamaño mínimo de bundle se puede calcular durante la simulación rastreando la cantidad de gas usado por el paso de validación de la cuenta, restando eso de verificationGasLimit , y luego calculando el tamaño mínimo a partir de lo que queda. Los bundlers pueden almacenar este valor junto con la UO en su mempool y usarlo como pista para la construcción de bundles.
💡 Una desventaja de este enfoque es que asume que el uso de gas por parte de un signature aggregator es uniforme por operación. Si este no es el caso, la medición podría trasladarse al contrato del aggregator y ser retornada por su función de verificación. Los bundlers necesitarían una forma de calcular estos valores no uniformes también off-chain.
¿Qué significa esto para los desarrolladores de signature aggregators?
Es probable que los signature aggregators necesiten ser incluidos directamente en listas blancas por los bundlers, proporcionándoles métodos para calcular firmas off-chain junto con sus componentes de costo de gas estático/dinámico. El problema del arranque en frío va a ser difícil, especialmente dada la imposibilidad de que un usuario "oferte" para acelerar su operación.
¿Qué significa esto para los desarrolladores de account clients?
Es importante entender las distinciones de L2 descritas arriba, especialmente a la hora de estimar comisiones de gas. En Optimism, si usas la priority fee provista por la red, puedes pagar en exceso de manera masiva por una user operation, ya que esta priority fee ahora también se aplica a los costos de L1. Si usas el endpoint de bundler de Alchemy, consulta nuestra documentación para conocer consejos sobre la estimación de comisiones.
🦀
Continúa leyendo
El siguiente artículo de esta serie sobre la estimación de gas de ERC-4337 ofrece un recorrido por el proceso de estimación de comisiones de user operations. Si te perdiste la parte uno o dos, aprende cómo funcionan la estimación de gas de ERC-4337, los valores dummy y el problema de las transferencias de tokens.
Boletín de Alchemy
Entérate primero de los lanzamientos
Suscríbete a nuestro boletín
Recibe las últimas actualizaciones de productos y recursos de Alchemy
Al ingresar tu correo electrónico, aceptas recibir nuestras comunicaciones de marketing y actualizaciones de productos. Reconoces que Alchemy procesa la información que recibimos de acuerdo con nuestro Aviso de Privacidad. Puedes cancelar tu suscripción en cualquier momento.
Artículos relacionados

Glamsterdam: la guía completa para desarrolladores de Ethereum
Glamsterdam ya está en Sepolia. La guía completa sobre lo que significa para los desarrolladores y cómo Alchemy se preparó para la actualización de la red.

Por qué los equipos de trading eligen Alchemy para RPC de baja latencia
Los equipos de trading eligen Alchemy por lecturas y escrituras de baja latencia cuando el mercado se mueve, y un registro confiable cuando el dinero se liquida, incluso en el volumen pico.

¿Con qué proveedor de RPC deberías construir en Tokio?
Comparamos cinco de los proveedores de RPC que sirven Tokio en cinco cadenas. Así se comparan, y dónde importan las diferencias para los equipos sensibles a la latencia.