Account abstraction parte 4: firmas agregadas
Escrito por David Philipson
Firmas agregadas
Nuestra implementación actual valida cada user op del bundle por separado. Esta es una forma muy directa de pensar la validación, pero potencialmente ineficiente. Verificar firmas puede terminar siendo costoso en términos de gas, porque requiere bastante aritmética criptográfica.
¿No sería bueno poder validar muchas ops a la vez con una sola firma en lugar de muchas?
Hacerlo depende de un concepto de criptografía: las firmas agregadas.
Un esquema de firmas que soporta agregación provee una forma, dados múltiples mensajes firmados con distintas claves, de generar una única firma combinada tal que verificar la firma combinada implica que todas las firmas constituyentes también son válidas.
Un ejemplo común de un esquema de firmas que soporta agregación es BLS.
Esta optimización es particularmente útil para implementar rollups, ya que el objetivo principal de un rollup es la compresión de datos, y la agregación de firmas nos permite comprimir la parte de la firma.
Para más información sobre el ahorro de espacio con la agregación de firmas, ver el tweet de Vitalik sobre el tema.
Presentando los agregadores
De inmediato, vemos que no todas las user ops de un bundle pueden tener sus firmas agregadas juntas. Recordemos que una wallet puede usar la lógica arbitraria que quiera para validar la firma que recibe, así que puede haber varios esquemas de firma presentes en el mismo bundle.
Dado que probablemente no podamos agregar firmas de distintos esquemas, nuestro bundle terminará con grupos de ops, cada grupo usando un esquema de agregación distinto o ningún esquema de agregación.
Dado que necesitamos tener varios esquemas de agregación representados on chain, cada uno con su propia lógica, haremos que cada esquema de agregación esté representado por un contrato al que llamaremos agregador.
Un esquema de agregación se define por cómo combina múltiples firmas en una y por cómo valida la firma combinada, así que un agregador expone estas dos funciones como métodos:

Dado que cada wallet define su propio esquema de firma, depende de cada wallet decidir con qué agregador es compatible, si es que hay alguno.
Si una wallet quiere participar en la agregación, expone un método para elegir su agregador:
Usando este nuevo método getAggregator, el bundler puede agrupar las ops que tienen el mismo agregador y usar el método aggregateSignatures de ese agregador para calcular una firma combinada para ellas.
Un grupo podría verse así:
💡 Si un bundler tiene conocimiento off-chain sobre un agregador en particular, puede optimizar codificando de forma nativa una versión del algoritmo de agregación de firmas en lugar de ejecutar aggregateSignatures como código EVM.
A continuación, necesitamos actualizar el contrato entry point para que haga uso de los nuevos agregadores.
Recordemos que el entry point tiene un método handleOps que recibe una lista de ops.
Le daremos un nuevo método, handleAggregatedOps, que hace lo mismo pero recibe las ops agrupadas por agregador:
El nuevo método, handleAggregatedOps, funciona en gran medida igual que handleOps. La única diferencia está en su paso de validación.
Mientras que handleOps realiza la validación llamando al método validateOp de cada wallet, handleAggregatedOps en cambio llamará al método validateSignatures del agregador sobre la firma combinada de cada grupo, usando el agregador de ese grupo.

¡Ya casi terminamos!
Pero hay un problema aquí que a estas alturas ya nos resulta bastante familiar.
El bundler quiere simular la validación y verificar que el agregador validará un grupo de ops antes de incluirlas en el bundle, porque si la validación falla, el bundler se ve obligado a pagar el gas. Pero un agregador con lógica arbitraria puede fácilmente tener éxito durante la simulación pero fallar durante la ejecución.
Resolveremos esto exactamente de la misma manera que lo hicimos para los paymasters y las factories: restringimos qué storage puede acceder el agregador y qué opcodes puede usar, y exigimos que haga stake de ETH en el entry point a menos que no acceda a storage.
¡Y eso es todo para las firmas agregadas!
Cierre
Lo que hemos creado aquí es, más o menos, la arquitectura completa de ERC-4337. Hay algunas diferencias en los detalles, como los nombres y argumentos de algunos métodos, pero no queda nada que yo consideraría una diferencia arquitectónica. Si hice bien mi trabajo, ahora deberías poder leer el ERC-4337 real y entender qué está pasando.
Si llegaste hasta acá, ¡muchas gracias por leer mi explicación! Espero que te haya ayudado tanto como a mí me ayudó escribirla.
Apéndice: diferencias con ERC-4337
Si bien ya tenemos la arquitectura general de account abstraction, las personas inteligentes detrás de ERC-4337 pensaron en algunas cosas que son un poco distintas de lo que describimos arriba.
¡Repasemos algunas de ellas!
1. Rangos de tiempo de validación
Arriba fui bastante impreciso sobre el tipo de retorno del validateOp de la wallet y del validatePaymasterOp del paymaster. ERC-4337 encuentra una buena forma de aprovechar esto.
Algo que a una wallet le gustaría mucho hacer es permitir que una user op sea válida solo por un cierto período de tiempo. De lo contrario, un bundler malicioso podría quedarse con esa operación durante mucho tiempo, y luego incluirla en un bundle mucho más tarde, en un momento que le resulte ventajoso al bundler.
La wallet podría querer defenderse de esto revisando el TIMESTAMP durante la validación para asegurarse de que no esté demasiado lejos en el futuro, pero no puede, porque hemos prohibido TIMESTAMP durante la validación para evitar que las simulaciones sean imprecisas. Esto significa que la wallet necesita otra forma de indicar en qué momentos la operación es válida.
Por eso, ERC-4337 le da a validateOp un valor de retorno que la wallet puede usar para elegir un rango de tiempo:
Este valor de retorno representa el rango de tiempo en el que la operación es válida como dos enteros de 8 bytes, uno después del otro.
Otra observación de ERC-4337: las wallets deben devolver un valor centinela desde validateOp en lugar de hacer revert en caso de que falle la validación, lo cual ayuda con la estimación de gas, porque eth_estimateGas no indica cuánto gas se usó en una transacción que hace revert.
2. Call data arbitrario para wallets y factories
Dijimos que la interfaz de nuestra wallet era:
En ERC-4337, las wallets en realidad no tienen un método llamado executeOp.
En cambio, la user operation tiene un campo callData:
Esto se pasa a la wallet como call data.
Para un contrato inteligente típico, los primeros cuatro bytes de estos datos se interpretarán como un selector de función y el resto como los argumentos de la función.
Esto significa que, aparte del método requerido validateOp, las wallets pueden definir su propia interfaz, y las user operations pueden usarse para llamar a métodos arbitrarios en la wallet.
En la misma línea, en ERC-4337 los contratos factory en realidad no tienen un método deployContract. También reciben call data arbitrario, en este caso desde el campo initCode de la op.
3. Datos compactos para paymasters y factories
Arriba dijimos que la user operation contenía campos para especificar un paymaster, así como qué datos pasarle:
En ERC-4337, estos se combinan en un solo campo como optimización, donde los primeros 20 bytes del campo son la dirección del paymaster y el resto son los datos:
Lo mismo ocurre con las factories y los datos que se les envían: mientras que nosotros usamos dos campos, factory y factoryData, ERC-4337 los combina en un único campo, initCode.
¡Bien, lo lograste!
Esperamos que hayas aprendido mucho sobre Account Abstraction.
Podrías haber inventado account abstraction
¿Te perdiste el comienzo de esta serie de 4 partes? ¡Volvé atrás y leé desde el principio!
Resúmenes relacionados
Wallets14 de octubre de 2026
¿Qué es un paymaster?
Un paymaster patrocina el gas de una user operation, o deja que el usuario pague esa tarifa con un token ERC-20.
Wallets2 de septiembre de 2026
Agent wallets: el modelo de sesiones y permisos para agentes de IA
Cómo los agentes de IA obtienen acceso a wallets con alcance limitado y revocable sin tener las llaves privadas: sesiones, firma delegada y revocación instantánea.
Wallets29 de julio de 2026
Deja de pegar claves privadas en Cursor: cómo darle una wallet a tu coding agent
Dale una wallet a tu coding agent sin darle la clave. Cómo los agent wallets de Alchemy CLI usan sesiones con alcance limitado para que los agentes transaccionen sin claves privadas en .env.

Construye magia blockchain
Alchemy combina los productos y herramientas de desarrollo Web3 más potentes con recursos, comunidad y un soporte legendario.