Account abstraction parte 4: assinaturas agregadas
Escrito por David Philipson
Assinaturas agregadas
Nossa implementação atual valida cada user op do bundle separadamente. Essa é uma forma bastante direta de pensar em validação, mas potencialmente custosa. Verificar assinaturas pode acabar sendo caro em termos de gas, porque isso exige bastante aritmética criptográfica.
Não seria bom se pudéssemos validar vários ops ao mesmo tempo com apenas uma assinatura, em vez de várias?
Fazer isso depende de um conceito da criptografia: assinaturas agregadas.
Um esquema de assinatura que suporta agregação fornece uma maneira, dadas várias mensagens assinadas com chaves diferentes, de gerar uma única assinatura combinada de forma que verificar a assinatura combinada implique que todas as assinaturas que a compõem também são válidas.
Um exemplo comum de esquema de assinatura que suporta agregação é o BLS.
Essa otimização é particularmente útil para implementar rollups, já que o principal objetivo de um rollup é a compressão de dados, e a agregação de assinaturas nos permite comprimir a parte referente às assinaturas.
Para mais detalhes sobre a economia de espaço obtida com a agregação de assinaturas, veja o tweet de Vitalik sobre o assunto.
Apresentando os aggregators
De imediato, percebemos que nem todos os user ops de um bundle podem ter suas assinaturas agregadas juntas. Lembre-se de que uma wallet tem permissão para usar qualquer lógica arbitrária que quiser para validar a assinatura que recebe, então pode haver vários esquemas de assinatura presentes no mesmo bundle.
Como provavelmente não conseguimos agregar assinaturas de esquemas diferentes, nosso bundle vai acabar com grupos de ops, cada grupo usando um esquema de agregação distinto ou nenhum esquema de agregação.
Como precisamos ter vários esquemas de agregação representados on chain, cada um com sua própria lógica, faremos com que cada esquema de agregação seja representado por um contrato que chamaremos de aggregator.
Um esquema de agregação é definido pela forma como combina várias assinaturas em uma só e pela forma como valida a assinatura combinada, então um aggregator expõe essas duas funções como métodos:

Como cada wallet define seu próprio esquema de assinatura, cabe a cada wallet decidir com qual aggregator ela é compatível, se for o caso.
Se uma wallet quiser participar da agregação, ela expõe um método para escolher seu aggregator:
Usando esse novo método getAggregator, o bundler pode agrupar ops que tenham o mesmo aggregator e usar o método aggregateSignatures desse aggregator para calcular uma assinatura combinada para eles.
Um grupo pode se parecer com isto:
💡 Se um bundler tiver conhecimento off-chain sobre um determinado aggregator, ele pode otimizar o processo codificando diretamente uma versão nativa do algoritmo de agregação de assinaturas, em vez de executar aggregateSignatures como código EVM.
Em seguida, precisamos atualizar o contrato entry point para fazer uso dos novos aggregators.
Lembre-se de que o entry point tem um método handleOps que recebe uma lista de ops.
Vamos dar a ele um novo método, handleAggregatedOps, que faz a mesma coisa, mas recebe os ops agrupados por aggregator:
O novo método, handleAggregatedOps, funciona basicamente da mesma forma que handleOps. A única diferença está na etapa de validação.
Enquanto handleOps realiza a validação chamando o método validateOp de cada wallet, handleAggregatedOps vai, em vez disso, chamar o método validateSignatures do aggregator sobre a assinatura combinada de cada grupo, usando o aggregator daquele grupo.

Estamos quase terminando!
Mas há uma questão aqui que já deve ser bem familiar.
O bundler quer simular a validação e verificar que o aggregator vai validar um grupo de ops antes de incluí-los no bundle, porque, se a validação falhar, o bundler é obrigado a pagar pelo gas. Mas um aggregator com lógica arbitrária pode facilmente ter sucesso durante a simulação e falhar durante a execução.
Vamos resolver isso exatamente da mesma forma que resolvemos para paymasters e factories: restringimos qual storage o aggregator pode acessar e quais opcodes ele pode usar, e exigimos que ele faça stake de ETH no entry point, a menos que não acesse storage.
E é isso para assinaturas agregadas!
Encerramento
O que criamos aqui é, mais ou menos, a arquitetura completa do ERC-4337! Há algumas diferenças nos detalhes, como os nomes e argumentos de alguns métodos, mas não há mais nada que eu consideraria uma diferença arquitetural. Se eu fiz um bom trabalho, agora você deve conseguir ler o ERC-4337 de verdade e entender o que está acontecendo.
Se você chegou até aqui, muito obrigado por ler minha explicação! Espero que ela tenha ajudado você tanto quanto me ajudou a escrevê-la.
Adendo: diferenças em relação ao ERC-4337
Embora já tenhamos entendido a arquitetura geral da abstração de contas, as pessoas inteligentes por trás do ERC-4337 pensaram em algumas coisas que são um pouco diferentes do que descrevemos acima.
Vamos ver algumas delas!
1. Intervalos de tempo de validação
Acima, fui bem vago sobre o tipo de retorno do validateOp da wallet e do validatePaymasterOp do paymaster. O ERC-4337 encontra uma boa forma de aproveitar isso.
Algo que uma wallet gostaria muito de fazer é permitir que um user op seja válido apenas por um determinado período de tempo. Caso contrário, um bundler mal-intencionado poderia guardar essa operação por muito tempo e, então, incluí-la em um bundle bem mais tarde, em um momento vantajoso para o bundler.
A wallet poderia querer se proteger disso verificando o TIMESTAMP durante a validação, para garantir que não está muito distante no futuro, mas não pode, porque proibimos o TIMESTAMP durante a validação para evitar que as simulações fiquem imprecisas. Isso significa que a wallet precisa de outra forma de indicar em quais momentos a operação é válida.
Assim, o ERC-4337 dá a validateOp** um valor de retorno que a wallet pode usar para escolher um intervalo de tempo:**
Esse valor de retorno representa o intervalo de tempo em que a operação é válida, como dois inteiros de 8 bytes, um após o outro.
Outra observação do ERC-4337: as wallets devem retornar um valor sentinela em validateOp em vez de reverter em caso de falha de validação, o que ajuda na estimativa de gas, já que o eth_estimateGas não informa quanto gas foi usado em uma transação que reverte.
2. Call data arbitrário para wallets e factories
Dissemos que a interface da nossa wallet era:
No ERC-4337, as wallets não têm, na verdade, um método chamado executeOp.
Em vez disso, a user operation tem um campo callData:
Isso é passado para a wallet como call data.
Para um contrato inteligente típico, os primeiros quatro bytes desses dados serão interpretados como um seletor de função, e o restante como argumentos da função.
Isso significa que, além do método validateOp obrigatório, as wallets podem definir sua própria interface, e as user operations podem ser usadas para chamar métodos arbitrários na wallet.
Na mesma linha, no ERC-4337 os contratos factory também não têm, na verdade, um método deployContract. Eles também recebem call data arbitrário, nesse caso a partir do campo initCode do op.
3. Dados compactos para paymasters e factories
Acima, dissemos que a user operation continha campos para especificar um paymaster, assim como quais dados passar a ele:
No ERC-4337, esses campos são combinados em um único campo como uma otimização, em que os primeiros 20 bytes do campo são o endereço do paymaster e o restante são os dados:
O mesmo vale para as factories e os dados enviados a elas: enquanto usamos dois campos, factory e factoryData, o ERC-4337 combina esses dois em um único campo, initCode.
Ok, você conseguiu!
Esperamos que você tenha aprendido bastante sobre Account Abstraction.
Você poderia ter inventado a abstração de contas
Perdeu o começo desta série de 4 partes? Volte e leia desde o início!
Visões gerais relacionadas
Carteiras14 de outubro de 2026
O que é um paymaster?
Um paymaster patrocina o gas de uma user operation, ou deixa o usuário pagar essa taxa com um token ERC-20.
Carteiras2 de setembro de 2026
Carteiras de agentes: o modelo de sessão e permissão para agentes de IA
Como agentes de IA obtêm acesso a carteiras com escopo definido e revogável, sem armazenar chaves privadas: sessões, assinatura delegada e revogação instantânea.
Carteiras29 de julho de 2026
Pare de colar chaves privadas no Cursor: como dar uma carteira ao seu agente de código
Dê uma carteira ao seu agente de código sem dar a chave. Como as carteiras de agente do Alchemy CLI usam sessões com escopo para que agentes transacionem sem chaves privadas no .env.

Construa magia blockchain
A Alchemy combina os produtos e ferramentas de desenvolvimento Web3 mais poderosos com recursos, comunidade e suporte lendário.