Skip to content

Latest commit

 

History

History
313 lines (239 loc) · 13.7 KB

rip-0000.md

File metadata and controls

313 lines (239 loc) · 13.7 KB
rip title description author discussions-to status type category created requires
0
Native Account Abstraction RPC methods
Native Account Abstraction specific RPC methods providing support for common user flows such as transaction gas estimation and view-only calls to smart contracts
Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn)
Draft
Standards Track
Core
2025-01-01
7560

Abstract

With the introduction of Account Abstraction as it is defined by RIP-7560 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 UserOperations as defined in ERC-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 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 such a value, 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:

{
  "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:

{
  "validationGasLimit": "0x9184e72a000",
  "paymasterValidationGasLimit":"0x9184e72a000",
  "paymasterPostOpGasLimit":"0x9184e72a000",
  "callGasLimit": "0x9184e72a000"
}

eth_callAA

Execute the AA transaction in memory without broadcasting it to the mempool or commiting 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 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 authorizationData 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
  • sigFail - 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:

{
  "returnData": "0xdeadbeef",
  "gasUsed": "0x1a14b",
  "status": "0x1",
  "sigFail":  "0x1",
  "sigFailPaymaster": "0x1",
  "logs": [
    {
      "transactionHash": "0x8fc90a6c3ee3001cdcbbb685b4fbe67b1fa2bec575b15b0395fea5540d0901ae",
      "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "blockHash": "0x58a945e1558810523df00490ff28cbe111b37851c44679ce5be1eeaebb4b4907",
      "blockNumber": "0xeb8822",
      "data": "0x000000000000000000000000000000000000000000000000000000001debea42",
      "logIndex": "0x6c",
      "removed": false,
      "topics": [
        "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
        "0x0000000000000000000000005067c042e35881843f2b31dfc2db1f4f272ef48c",
        "0x0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585"
      ],
      "transactionIndex": "0x4e"
    }
  ]
}

wallet_prepareTransactionAA

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.

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_esimateGasAA 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.

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 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.