diff --git a/RIPS/rip-0000.md b/RIPS/rip-0000.md new file mode 100644 index 0000000..445ac4d --- /dev/null +++ b/RIPS/rip-0000.md @@ -0,0 +1,314 @@ +--- +rip: 0000 +title: Native Account Abstraction RPC methods +description: Native Account Abstraction specific RPC methods providing support for common user flows such as transaction gas estimation and view-only calls to smart contracts +author: Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn) +discussions-to: +status: Draft +type: Standards Track +category: Core +created: 2025-01-01 +requires: 7560 +--- + +## Abstract + +With the introduction of Account Abstraction as it is defined by [RIP-7560](./rip-7560.md) +a number of existing RPC APIs are not capable of providing the necessary functionality. +The required behaviour changes are significant enough to require an introduction of completely new methods +to the Ethereum L2 clients implementing Account Abstraction. + +## Motivation + +The process of creating a transaction has been getting increasingly more complex and interactive process +with the growing complexity of on-chain protocols. +The introduction of Account Abstraction introduces a new dimension for this complexity. + +As the AA transactions are executed atomically but consist of multiple sequential frames, +it is not possible to reliably prepare parts of the AA transaction individually. + +For example, when creating an AA transaction that also performs a deployment of a `sender` smart account, +it is all but impossible to perform a gas estimation for the execution frame using the existing `eth_estimateGas` API. + +Instead, an API specifically designed with Account Abstraction in mind must be used. + +## Specification + +This document defines the API that the RIP-7560 compatible Ethereum nodes provide to the Smart Wallet applications. + +### eth_estimateGasAA + +Estimate the amount of gas needed per frame of an AA transaction. +Performs a search for gas limit values required to make each of the frames of the RIP-7560 transaction execute +successfully and without running out of gas. + +This method is an equivalent to the legacy Ethereum `eth_estimateGas` RPC API method. +This method is also a native AA equivalent to the `eth_estimateUserOperationGas` method for +[ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) UserOperations as defined in +[ERC-7769](https://eips.ethereum.org/EIPS/eip-7769). + +For validation frames, only valid calls to an appropriate `AA_ENTRY_POINT` callback, +such as `acceptAccount`, `acceptPaymaster`, `sigFailAccount` and `sigFailPaymaster`, are considered a success. + +Note, that in order for `eth_esimateGasAA` to function, both the wallet and the paymaster must correctly +implement signature checks as described in RIP-7560.\ +Most notably, the fields `senderValidationData` and `paymasterData` usually contain signatures for the transaction +and therefore cannot be known before the transaction preparation is complete.\ +The recommended solution to this problem is for the wallet to provide **stub data** for these contracts, +as described in the [Suggested Paymaster Flow](#suggested-paymaster-flow) section. + +Once a signature verification over the **stub data** fails, the validation code must not revert or finish execution, +but instead proceed as usual until making a `sigFailAccount` or `sigFailPaymaster` call accordingly.\ +A contract that does not provide proper gas estimation capability, such as described above, may cause `eth_esimateGasAA` to provide inconsistent results and risks incorrect reverts of validation frames, thus making the transaction invalid. + +The `eth_esimateGasAA` API optionally accepts the `State Override Set` object to allow users to modify +the state during the gas estimation. +This field as well as its behavior is equivalent to the ones defined for the `eth_call` RPC method. + +If it fails to find correct gas limit values for any of the frames, returns an error message with the detailed description of the failure reason. + +Parameters: + +1. OBJECT - The RIP-7560 transaction object. + The `validationGasLimit`, paymasterValidationGasLimit, `paymasterGasLimit` and `callGasLimit` fields are optional. +2. QUANTITY | TAG - integer block number, or the string "latest", "earliest", "pending", "safe" or "finalized" +3. OBJECT - `State Override Set` + The `State Override Set` option allows you to change the state of a contract before executing the call. This means you + can modify the values of variables stored in the contract, such as balances and approvals for that call without + actually modifying the contract on the blockchain. + This behavior is equivalent to the one defined for the `eth_call` RPC method. + +Example: +```json +{ + "id": 1, + "jsonrpc": "2.0", + "method": "eth_estimateGasAA", + "params": [ + { + "sender": "0x783Ca0bD27E42357D6Dbc87E9Cf9eb3a8D513843", + "senderValidationData": "0xdeadbeef", + "deployer": "0xD6E4aA932147A3FE5311dA1b67D9e73da06F9cEf", + "deployerData": "0xdeadbeef", + "paymaster": "0x8410373DF6E9b20765c9599c26d585B2cd0Ef628", + "paymasterData": "0xdeadbeef", + "executionData": "0xdeadbeef", + "builderFee": "0x9184e72a000", + "maxPriorityFeePerGas": "0x9184e72a000", + "maxFeePerGas": "0x9184e72a000", + "accessList": [], + "authorizationList": [ + { + "chainId": "0x1", + "nonce": "0x15", + "yParity": "0x25", + "r": "0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea", + "s": "0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c" + } + ] + }, + "latest", + { + "0x1111111111111111111111111111111111111111": { + "balance": "0x9184e72a000", + "nonce": "0x1", + "code": "0xdeadbeef", + "state": { + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x1" + }, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x1" + } + } + } + ] +} +``` +Returns: + +| Name | Type | Comment | +|-----------------------------|----------|------------------------------------------------------------| +| validationGasLimit | QUANTITY | | +| callGasLimit | QUANTITY | | +| paymasterValidationGasLimit | QUANTITY | if `paymaster` is set, `null` otherwise | +| paymasterPostOpGasLimit | QUANTITY | if `paymaster` is set, `0` if not needed, `null` otherwise | + +Example: + +```json +{ + "validationGasLimit": "0x9184e72a000", + "paymasterValidationGasLimit":"0x9184e72a000", + "paymasterPostOpGasLimit":"0x9184e72a000", + "callGasLimit": "0x9184e72a000" +} +``` + +### eth_callAA + +Execute the AA transaction in memory without broadcasting it to the mempool or committing it to the blockchain. +An equivalent to the legacy Ethereum `eth_call` RPC API method. + +Inputs are equivalent to the ones defined for the [eth_estimateGasAA](#eth_estimategasaa) method. + +User can also provide the gas limit for all or some of the AA transaction frames.\ +If gas limits are not provided, the RPC node provider is free to choose a default value.\ +The RPC node provider should also choose a maximum acceptable gas limit value taking into consideration the +block gas limit and other rules of the underlying L2 protocol. + +Does not require the transaction to be properly signed, meaning it continues execution after either an account +or a paymaster contract make a `sigFailAccount` or `sigFailPaymaster` call. + +Returns the data that is returned by the top-level execution frame, gas usage info, +as well as the full array of event logs emitted during the execution of the RIP-7560 transaction + +If any of the validation or execution frames reverts, returns an error object containing the revert message. + +Inputs: + +1. OBJECT - The RIP-7560 transaction object. + The `senderValidationData` field is optional. +2. QUANTITY | TAG - integer block number, or the string "latest", "earliest", "pending", "safe" or "finalized" + +Returns: + +- **returnData** - DATA - the return value of the `sender` execution frame +- **gasUsed** - QUANTITY - the total amount of gas used by the transaction +- **sigFailAccount** - QUANTITY - whether account called "sigFailAccount" or not +- **sigFailPaymaster** - QUANTITY - whether paymaster called "sigFailPaymaster" or not +- **status** - QUANTITY - whether the execution phase including the `paymasterPostOp` completed successfully +- **logs** - ARRAY - an array of the event logs emitted during the transaction + +Example: +```json +{ + "returnData": "0xdeadbeef", + "gasUsed": "0x1a14b", + "status": "0x1", + "sigFailAccount": "0x1", + "sigFailPaymaster": "0x1", + "logs": [ + { + "transactionHash": "0x8fc90a6c3ee3001cdcbbb685b4fbe67b1fa2bec575b15b0395fea5540d0901ae", + "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "blockHash": "0x58a945e1558810523df00490ff28cbe111b37851c44679ce5be1eeaebb4b4907", + "blockNumber": "0xeb8822", + "data": "0x000000000000000000000000000000000000000000000000000000001debea42", + "logIndex": "0x6c", + "removed": false, + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000005067c042e35881843f2b31dfc2db1f4f272ef48c", + "0x0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585" + ], + "transactionIndex": "0x4e" + } + ] +} +``` + +### Suggested wallet flow +The wallet should expose `wallet_prepareTransactionAA` or an equivalent API, to be called by dApps communicating with the wallet. + +The `wallet_prepareTransactionAA` API is meant to be implemented by the wallet application, +and not the L2 client RPC node provider. + +The method accepts a partially filled RIP-7560 transaction object and fills in all the missing fields.\ +These may include gas prices, gas limits, nonces etc.\ +All parameters are optional. If the parameter is provided with a value, calling this method will never override it. + +The method returns the full transaction object that can be serialized and sent to the `eth_sendRawTransaction` API. + +In case the wallet was not able to fill the transaction object for any reason, +the `wallet_prepareTransactionAA` method returns an appropriate error code. + +### Suggested paymaster flow + +The Paymaster service should expose the `pm_getPaymasterStubData` and `pm_getPaymasterData` APIs as defined by the +[ERC-7677](https://eips.ethereum.org/EIPS/eip-7677). + +The API defined there should be implemented by a third party paymaster service, +and not by the L2 client RPC node provider. + +This API is expected to be used internally by the wallet application as part of the `wallet_prepareTransactionAA` flow. + +### Add Account Abstraction support for all transaction-level RPC APIs + +This includes the following APIs: +`eth_sendTransaction`, +`eth_sendRawTransaction`, +`eth_getTransactionByHash`, +`eth_getTransactionReceipt`, +`eth_getTransactionByBlockHashAndIndex`, +`eth_getTransactionByBlockNumberAndIndex`. + +These methods have a very similar purpose and should support returning the new transaction type object. + +Note that the "transaction index position" is determined by the position of the transaction's **validation frame**. + +### Errors + +Error format: + +- DATA - The revert data of the first reverted frame. +- CODE - The error code indicating the type of error, which may include the entity that caused the revert on-chain. +- MESSAGE - The human-readable error that may include a decoding of the `DATA` field if possible. + +Error codes: + +* code: -32500 - transaction validation failed by `sender`. + The message field SHOULD be set to the revert message and data from the `sender`. + +* code: -32501 - transaction validation failed by `paymaster`. + The message field SHOULD be set to the revert message and data from the `paymaster`. + +* code: -32502 - transaction validation failed by `deployer` + The message field SHOULD be set to the revert message and data from the `deployer`. + +* code: -32503 - Transaction out of time range. + The message field SHOULD include the requested time range and the current block timestamp. + + +## Rationale + +### New methods instead of modification for existing ones + +While the `eth_esimateGasAA` and `eth_callAA` methods are simply RIP-7560 extensions of the existing +`eth_esimateGas` and `eth_call` methods accordingly, +the type of the return values for the existing methods does not match the needs of the Native Account Abstraction API. + +The approach of creating a new set of methods is cleaner in the long term as these methods may be used later in the +EOF-based Native Account Abstraction as described in [EIP-7701](https://eips.ethereum.org/EIPS/eip-7701). + +### The `eth_callAA` returned data format + +The legacy `eth_call` method returns a single DATA array representing the return data of the single top-level +call frame of a legacy transaction. + +However, this approach would not be sufficiently useful for the Native Account Abstraction solution.\ +The top-level frame of the execution phase is a call to the `sender` smart account that may consist of multiple +inner batched calls. + +Furthermore, the code in the `sender` address is frequently just +a proxy contract that does not propagate the implementation's returned data. + +In order to allow smart contract wallets to reliably expose any data to the off-chain execution we have little choice +but to rely on the existing mechanism of emitting the event logs. + +## Backwards Compatibility + +The added methods are not interfering with any existing code and should pose no backwards compatibility issues. + +## Security Considerations + +### Estimate Gas flow in smart contracts + +As mentioned in the [eth_estimateGasAA](#eth_estimategasaa) section, the `sender` and `paymaster` smart contracts +are expected to explicitly implement a special code flow to support the gas estimation. + +This code is supposed to only be executable during the `eth_estimateGasAA` and MUST never result in a valid transaction. +In case this constraint is violated the contract will be vulnerable to various potential threats. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md).