# Entendiendo e implementando EIP-7702

> Digamos que intentas ejecutar una transacción atómica compleja todo en uno que requiere intercambiar tokens, añadir liquidez y hacer staking de recompensas. Pero resulta que tu wallet EOA normal de Ethereum no puede hacer transacciones por lotes.

Por Shodipo Ayomide, publicado el 27 sept 2025. Versión web: https://blog.shodipoayomide.com/es/understanding-and-implementing-eip-7702

![Entendiendo e implementando EIP-7702](https://blog.shodipoayomide.com/banners/understanding-and-implementing-eip-7702.png)

Digamos que intentas ejecutar una transacción atómica compleja todo en uno que requiere intercambiar tokens, añadir liquidez y hacer staking de recompensas. Pero resulta que tu wallet EOA normal de Ethereum no puede hacer transacciones por lotes. Así que tendrás que firmar tres transacciones separadas, pagar gas tres veces, lo cual es un no rotundo, y luego rezar para que los bots de MEV no te hagan un sandwich entre un paso y otro.

Esta es una de las conversaciones más acaloradas del ecosistema `EVM` últimamente, ¿cómo les damos exactamente superpoderes a las wallets normales sin romperlo todo al mismo tiempo?

De este reto salieron dos `EIPs`, `EIP-3074` y después `EIP-7702`. Ambas buscan cerrar la brecha entre una `EOA` simple y las `smart contract accounts`, pero toman enfoques distintos para delegar autoridad. Una ofrece un poder persistente con el que las cosas pueden salir muy mal y tus wallets pueden acabar vaciadas. La otra puede darte tanto delegación persistente como delegación temporal, que podría desaparecer en el momento en que tu transacción se ejecuta on-chain.

Hablemos de por qué importa esta diferencia y de cómo la propuesta de Vitalik podría haber salvado a Ethereum de una posible pesadilla de seguridad.

## EIP-2718 - Sobre de transacción tipado

Antes de entrar en el tema de la delegación, hay una pieza importante de infraestructura que hace posible todo esto, y es `EIP-2718`. Piensa en ella como el sistema de contenedores de envío de Ethereum para las transacciones.

```typescript
// before eip-2718 all transactions looked the same
const legacyTx = rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s]);

// after eip-2718 transactions can now be typed
const typedTx = TransactionType || TransactionPayload;
```

`EIP-2718` introduce los `Typed Transaction Envelopes`, donde `TransactionType || TransactionPayload` es una transacción válida. `TransactionType` identifica el formato de la transacción, mientras que `Payload` contiene el contenido de la transacción. Ahora, este sistema de envoltorio significa que podemos introducir comportamientos de transacción totalmente nuevos sin romper la funcionalidad existente.

Al introducir un tipo de transacción sobre, solo tenemos que garantizar la compatibilidad con las transacciones existentes, y a partir de ahí solo hay que resolver el problema mucho más simple de asegurar que no haya conflictos de numeración entre `TransactionTypes`. Así que cuando `EIP-7702` necesitó introducir su mecanismo de delegación temporal, pudo simplemente definir un nuevo tipo de transacción, por ejemplo `0x04`, sin requerir ningún cambio en la propia `EVM`.

## EIP-3074 - Enfoque de delegación persistente

[EIP-3074](https://eips.ethereum.org/EIPS/eip-3074) adoptó un enfoque audaz para la delegación, dando a las `EOAs` la capacidad de delegar autoridad de forma permanente a contratos inteligentes mediante dos nuevos `opcodes` de la `EVM` - `AUTH` y `AUTHCALL`.

### Cómo funcionan AUTH y AUTHCALL

El mecanismo es sencillo

```solidity
// user signs an auth message
bytes32 commit = keccak256(abi.encode(invokerAddress, batchActions));
bytes memory signature = signMessage(userPrivateKey, commit);

// invoker contract calls AUTH opcode
AUTH(commit, signature.v, signature.r, signature.s);
// This sets the 'authorized' context variable to user's address

// now invoker can make calls as the user
AUTHCALL(gasLimit, targetContract, 0, 0, calldata, calldataLength, 0, 0);
```

`AUTH` recibe cuatro parámetros, `commit` y los valores `yParity`, `r` y `s` de la firma, y si la firma es válida y la dirección del firmante es igual a la autoridad, la variable de contexto authorized se establece en esa autoridad. Luego `AUTHCALL` permite que el contrato invoker autorizado envíe transacciones, con `CALLER` establecido en la dirección autorizada en lugar de la del invoker.

Ahora, imagina un contrato invoker que pudiera manejar transacciones por lotes

```solidity
contract BatchInvoker {
    struct BatchCall {
        address target;
        bytes data;
        uint256 value;
    }
    
    function executeBatch(
        BatchCall[] calldata calls,
        bytes32 commit,
        uint8 v, bytes32 r, bytes32 s
    ) external {
        // authorize the user
        AUTH(commit, v, r, s);
        
        // Execute all calls as the user
        for (uint i = 0; i < calls.length; i++) {
            AUTHCALL(
                gasleft(),
                calls[i].target,
                calls[i].value,
                0, // valueExt (must be 0 for now)
                // ... calldata parameters
            );
        }
    }
}
```

Por muy emocionante que sea esto, estos dos `opcodes` generaron una serie de preocupaciones de seguridad en la comunidad `EVM`. La variable de contexto `authorized` persiste durante todo un mismo frame de ejecución del contrato, pero no se pasa a través de ninguna llamada, incluida `DELEGATECALL`. Básicamente, esto significa que la autorización está activa durante todo el alcance de la transacción.

El problema real no es su naturaleza temporal dentro de una transacción, sino lo que pasa cuando tienes contratos invoker muy usados. Si con el tiempo todo el mundo va a usar smart accounts, los `opcodes` `AUTH` y `AUTHCALL` pueden ser una enorme carga técnica y añadir complejidad a la propia `EVM`.

¿Qué pasa cuando un contrato invoker popular como el de arriba tiene un bug? De repente, cada usuario que alguna vez haya autorizado ese contrato podría estar en riesgo. Una actualización maliciosa, un caso límite que se pasó por alto, un desbordamiento de enteros y listo, empieza un vaciado masivo.

El ecosistema `EVM` se dio cuenta de que esto creaba una dinámica extraña. El modelo de seguridad de `EIP-3074` depende mucho del contrato invoker. Como muchos usuarios podrían depender de la misma lógica de invoker, una vulnerabilidad o exploit en un solo invoker podría comprometer los activos o permisos de muchos usuarios a la vez, y por eso se retiró `EIP-3074`.

## EIP-7702 - La solución de delegación flexible

Ahora, [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702), propuesta por Vitalik en mayo de 2024, llegó a `mainnet` con la `pectra upgrade` en mayo de 2025 e introduce un enfoque nuevo y simplificado, que permite a las `EOAs` funcionar temporalmente como contratos inteligentes durante una sola transacción, ¡y eso es algo muy importante!

En lugar de nuevos `opcodes`, `EIP-7702` aprovecha el sistema de sobres de transacción de `EIP-2718's` para introducir un nuevo tipo de transacción

```typescript
interface EIP7702Transaction {
    chainId: number;
    nonce: number;
    maxPriorityFeePerGas: bigint;
    maxFeePerGas: bigint;
    gasLimit: bigint;
    to: string;
    value: bigint;
    data: Uint8Array;
    accessList: AccessList;
    authorizationList: Authorization[];
}

interface Authorization {
    chainId: number;
    address: string;  // the address of the contract code to delegate to
    nonce: number;
    yParity: 0 | 1;
    r: Uint8Array;
    s: Uint8Array;
}
```

Por cada objeto de autorización, se escribe un indicador de delegación `(0xef0100 || address)` en el código de la cuenta que autoriza. Todas las operaciones que ejecutan código deben cargar y ejecutar el código al que apunta la delegación.

### Cómo funciona realmente la persistencia de la delegación
Aquí es donde mucha gente se confunde. `EIP-7702` ha evolucionado desde su borrador original. Al principio, la propuesta se diseñó para que las `EOAs` fueran inteligentes de forma temporal durante una sola transacción. Pero la versión final te da el control sobre cuánto dura la delegación.

```javascript
function processEIP7702Transaction(tx) {
    // verify all auth signatures
    for (const auth of tx.authorizationList) {
        const signer = recoverSigner(auth);
        if (signer !== getAddressFromAuth(auth)) {
            throw new Error("Invalid authorization");
        }
    }
    
    // set delegation pointers (these persist after transaction)
    for (const auth of tx.authorizationList) {
        const eoaAddress = getAddressFromAuth(auth);
        
        // set delegation pointer - 0xef0100 || contract_address
        const delegationPointer = concat(['0xef0100', auth.address]);
        setCode(eoaAddress, delegationPointer);
        
        // nowm this delegation PERSISTS unless explicitly cleared
    }
    
    // execute the transaction normally
    executeTransaction(tx);
    
    // no auto cleanup, delegation stays active
}
```

**NOTA:** Si la ejecución de una transacción `7702` falla, los indicadores de delegación ya procesados no se revierten y persisten a menos que se borren explícitamente estableciendo la dirección de delegación en `0x0` en una transacción `7702` posterior.

Esto significa que tienes tres patrones de delegación:

- Delegación persistente: Establece la delegación y la sigue usando a lo largo de varias transacciones
- Delegación temporal: Establece la delegación para casos de uso específicos, como delegar a un `Batching Contract` durante un día, aunque la delegación en sí es persistente hasta que la borres.

### Opciones temporales Y persistentes

Lo bueno de `EIP-7702` es que te da la opción de elegir. ¿Quieres una delegación temporal para una transacción compleja puntual? Puedes hacerlo. ¿Quieres actualizar tu `EOA` de forma persistente para que actúe como una wallet de contrato inteligente? También puedes hacerlo.

Para la delegación temporal, aquí tienes un ejemplo

```typescript
// one off delegation
const tempDelegationTx = {
    type: 0x04,
    authorizationList: [{
        address: batchExecutorContract,
        // ... auth details
    }],
    to: userAddress,
    data: encodeBatchCall([
        // execute your complex operation
        swapTokens(),
        addLiquidity(), 
        stakeRewards(),
    ])
};
```
Y para la delegación persistente, aquí tienes un ejemplo

```typescript
// upgrade EOA to smart wallet
const persistentDelegationTx = {
    type: 0x04,
    authorizationList: [{
        address: smartWalletImplementation,
        // ... auth details  
    }],
    to: userAddress,
    data: encodeCall("initializeSmartFeatures", [])
    // this delegation persists for future txns
};

// later txns can now use smart wallet features
const futureTransaction = {
    to: userAddress, // your EOA will now execute smart wallet code
    data: encodeCall("batchExecute", [multipleOperations])
    // no new auth needed
};
```

### Por qué 7702 es más segura

La diferencia clave entre `EIP-3074` y `EIP-7702` no es solo temporal vs. persistente, sino la distribución del riesgo y el control. `EIP-3074` crea un punto de fallo compartido en el que el problema de un contrato popular podría afectar a miles de usuarios. `EIP-7702` aísla cada transacción, así que los bugs solo podrían afectar a esa transacción concreta. `EIP-7702` es totalmente compatible con el `ERC-4337` existente y no requiere nuevos `opcodes`. Básicamente, esto significa que las wallets pueden adoptarla de forma gradual sin romper ningún sistema existente.

La idea clave es que son las `wallets`, y no las `dApps`, las que gestionan las delegaciones. Así que el acuerdo general es permitir que solo las wallets gestionen las delegaciones, lo que significa que:

- Las dApps no pueden controlar directamente tu delegación
- Los proveedores de wallets implementan una lógica de delegación revisada y auditada
- El riesgo se distribuye entre muchas implementaciones en lugar de concentrarse en unos pocos contratos invoker populares

## Lo que los devs necesitan saber

Si estás construyendo una aplicación que va a soportar `EIP-7702`, hay algunas cosas técnicas a tener en cuenta

1. **Cambios en la construcción de transacciones**
Tu lógica de construcción de transacciones tiene que manejar listas de autorización

```typescript
// old: simple EOA transaction
const tx = {
    to: contractAddress,
    data: encodedCall,
    // ... standard fields
};

// new way with eip-7702 delegation
const tx = {
    type: 0x04,
    to: userAddress, // calling user's own address
    data: encodeBatchCall([
        contract.interface.encodeFunctionData("swap", [tokenA, tokenB, amount]),
        contract.interface.encodeFunctionData("addLiquidity", [lpTokens]),
        contract.interface.encodeFunctionData("stake", [lpAmount])
    ]),
    authorizationList: [{
        address: batchExecutorImplementation,
        // ... authorization signature
    }],
    // ... standard fields
};
```

2. **Complejidad en la estimación de gas**
Si la EOA decide revocar el control del contrato inteligente, hay que enviar otra transacción `7702` para volver a establecer la delegación en `0x0`. Esto significa que tu estimación de gas tiene que tener en cuenta

- La verificación de la firma de autorización
- La configuración del puntero de código
- La ejecución en sí
- La sobrecarga de la limpieza

3. **Soporte de firmas de contratos inteligentes**
`EIP-7702` habilita la verificación de firmas `EIP-1271` para las `EOAs`. Esto significa que tu `EOA` **actualizada** puede firmar mensajes con métodos alternativos como las `passkeys`, manteniendo la compatibilidad con versiones anteriores.

```solidity
// your EOA can now implement smart signature verification
function isValidSignature(bytes32 hash, bytes signature) external view returns (bytes4) {
    // can verify passkey signatures, multisig, etc.
    if (verifyPasskeySignature(hash, signature)) {
        return 0x1626ba7e; // EIP-1271 magic value
    }
    return 0xffffffff;
}
```

## Enlaces esenciales

- [EIP-2718: Sobre de transacción tipado](https://eips.ethereum.org/EIPS/eip-2718) - El sistema base de sobres de transacción
- [EIP-3074: Opcodes AUTH y AUTHCALL](https://eips.ethereum.org/EIPS/eip-3074) - La propuesta de delegación persistente
- [EIP-7702: Establecer el código de una cuenta EOA para una transacción](https://eips.ethereum.org/EIPS/eip-7702) - La propuesta de delegación temporal
- [Discusión en Ethereum Magicians](https://ethereum-magicians.org/t/eip-set-eoa-account-code-for-one-transaction/19923) - Debate de la comunidad sobre EIP-7702
- [La hoja de ruta de abstracción de cuentas de Vitalik](https://ethereum-magicians.org/t/eip-set-eoa-account-code-for-one-transaction/19923)
