├── .gitignore ├── LICENSE.md ├── README.md ├── RIPS ├── rip-7212.md ├── rip-7560.md ├── rip-7614.md ├── rip-7696.md ├── rip-7711.md ├── rip-7712.md ├── rip-7728.md ├── rip-7740.md ├── rip-7755.md ├── rip-7759.md ├── rip-7767.md ├── rip-7810.md ├── rip-7859.md ├── rip-7875.md ├── rip-7952.md └── rip-7953.md └── assets ├── rip-7212 ├── benchstat_compare_test ├── ecrecover_benchmark_test └── p256Verify_benchmark_test ├── rip-7560 ├── flow_diagram.png ├── unused_gas_attack_overview.png └── zoom_into_transaction.png ├── rip-7711 ├── rip_7560_block_overview.png └── rip_7711_block_overview.png ├── rip-7755 ├── call_delivery_magicspend.png ├── call_delivery_precheck.png ├── call_delivery_userop.png ├── cancelled_request.png ├── happy_case.png ├── happy_case_precheck.png ├── request_flow_finality_delay.png └── state_root_sharing.png └── rip-7810 └── RIP_process.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor files 2 | .gitpod.yml 3 | .DS_Store 4 | /.idea -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rollup Improvement Proposals (RIPs) 2 | 3 | > **_ATTENTION_**: The RIPs repository is in the startup phase, and so is undergoing many changes. Both the process and how RIPs will be written and governed is still being worked on. Feedback encouraged on [Ethereum Magicians](https://ethereum-magicians.org/). 4 | 5 | The goal of the RIP project is to standardize and provide high-quality documentation for Rollups in Ethereum ecosystem. This repository tracks past and ongoing improvements to Ethereum's Rollup ecosystem in the form of Rollup Improvement Proposals (RIPs). 6 | 7 | **All RIPs are optional.** RIPs are and will always remain optional standards for Rollups and participants in the larger EVM ecosystem. RIPs and RollCall are not a governance process. 8 | -------------------------------------------------------------------------------- /RIPS/rip-7212.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7212 3 | title: Precompile for secp256r1 Curve Support 4 | description: Proposal to add precompiled contract that performs signature verifications in the “secp256r1” elliptic curve. 5 | author: Ulaş Erdoğan (@ulerdogan), Doğan Alpaslan (@doganalpaslan) 6 | discussions-to: https://ethereum-magicians.org/t/eip-7212-precompiled-for-secp256r1-curve-support/14789 7 | status: Final 8 | type: Standards Track 9 | category: Core 10 | created: 2023-06-22 11 | --- 12 | 13 | ## Abstract 14 | 15 | This proposal creates a precompiled contract that performs signature verifications in the “secp256r1” elliptic curve by given parameters of message hash, `r` and `s` components of the signature, `x` and `y` coordinates of the public key. So that, any EVM chain - principally Ethereum rollups - will be able to integrate this precompiled contract easily. 16 | 17 | ## Motivation 18 | 19 | “secp256r1” elliptic curve is a standardized curve by NIST which has the same calculations by different input parameters with “secp256k1” elliptic curve used by the “ecrecover” precompiled contract. The cost of combined attacks and the security conditions are almost the same for both curves. Adding a precompiled contract which is similar to "ecrecover" can provide signature verifications using the “secp256r1” elliptic curve in the smart contracts and multi-faceted benefits can occur. One important factor is that this curve is widely used and supported in many modern devices such as Apple’s Secure Enclave, Webauthn, Android Keychain which proves the user adoption. Additionally, the introduction of this precompiled contract could enable valuable features in the account abstraction which allows more efficient and flexible management of accounts by transaction signs in mobile devices. 20 | Most of the modern devices and applications rely on the “secp256r1” elliptic curve. The addition of this precompiled contract enables the verification of device native transaction signing mechanisms. For example: 21 | 22 | 1. **Apple's Secure Enclave:** There is a separate “Trusted Execution Environment” in Apple hardware which can sign arbitrary messages and can only be accessed by biometric identification. 23 | 2. **Webauthn:** Web Authentication (WebAuthn) is a web standard published by the World Wide Web Consortium (W3C). WebAuthn aims to standardize an interface for authenticating users to web-based applications and services using public-key cryptography. It is being used by almost all of the modern web browsers. 24 | 3. **Android Keystore:** Android Keystore is an API that manages the private keys and signing methods. The private keys are not processed while using Keystore as the applications’ signing method. Also, it can be done in the “Trusted Execution Environment” in the microchip. 25 | 4. **Passkeys:** Passkeys is utilizing FIDO Alliance and W3C standards. It replaces passwords with cryptographic key-pairs which is also can be used for the elliptic curve cryptography. 26 | 27 | Modern devices have these signing mechanisms that are designed to be more secure and they are able to sign transaction data, but none of the current wallets are utilizing these signing mechanisms. So, these secure signing methods can be enabled by the proposed precompiled contract to initiate the transactions natively from the devices and also, can be used for the key management. This proposal aims to reach maximum security and convenience for the key management. 28 | 29 | ## Specification 30 | 31 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. 32 | 33 | As of `FORK_TIMESTAMP` in the integrated EVM chain, add precompiled contract `P256VERIFY` for signature verifications in the “secp256r1” elliptic curve at address `PRECOMPILED_ADDRESS` in `0x100` (indicates 0x0000000000000000000000000000000000000100). 34 | 35 | ### Elliptic Curve Information 36 | 37 | “secp256r1” is a specific elliptic curve, also known as “P-256” and “prime256v1” curves. The curve is defined with the following equation and domain parameters: 38 | 39 | ``` 40 | # curve: short weierstrass form 41 | y^2 ≡ x^3 + ax + b 42 | 43 | # p: curve prime field modulus 44 | 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff 45 | 46 | # a: elliptic curve short weierstrass first coefficient 47 | 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc 48 | 49 | # b: elliptic curve short weierstrass second coefficient 50 | 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b 51 | 52 | # G: base point of the subgroup 53 | (0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, 54 | 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5) 55 | 56 | # n: subgroup order (number of points) 57 | 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 58 | 59 | # h: cofactor of the subgroup 60 | 0x1 61 | 62 | ``` 63 | 64 | ### Elliptic Curve Signature Verification Steps 65 | 66 | The signature verifying algorithm takes the signed message hash, the signature components provided by the “secp256r1” curve algorithm, and the public key derived from the signer private key. The verification can be done with the following steps: 67 | 68 | ``` 69 | # h (message hash) 70 | # pubKey = (public key of the signer private key) 71 | 72 | # Calculate the modular inverse of the signature proof: 73 | s1 = s^(−1) (mod n) 74 | 75 | # Recover the random point used during the signing: 76 | R' = (h * s1) * G + (r * s1) * pubKey 77 | 78 | # Take from R' its x-coordinate: 79 | r' = R'.x 80 | 81 | # Calculate the signature validation result by comparing whether: 82 | r' == r 83 | 84 | ``` 85 | 86 | ### Required Checks in Verification 87 | 88 | The following requirements **MUST** be checked by the precompiled contract to verify signature components are valid: 89 | 90 | - Verify that the `r` and `s` values are in `(0, n)` (exclusive) where `n` is the order of the subgroup. 91 | - Verify that the point formed by `(x, y)` is on the curve and that both `x` and `y` are in `[0, p)` (inclusive 0, exclusive p) where `p` is the prime field modulus. Note that many implementations use `(0, 0)` as the reference point at infinity, which is not on the curve and should therefore be rejected. 92 | 93 | ### Precompiled Contract Specification 94 | 95 | The `P256VERIFY` precompiled contract is proposed with the following input and outputs, which are big-endian values: 96 | 97 | - **Input data:** 160 bytes of data including: 98 | - 32 bytes of the signed data `hash` 99 | - 32 bytes of the `r` component of the signature 100 | - 32 bytes of the `s` component of the signature 101 | - 32 bytes of the `x` coordinate of the public key 102 | - 32 bytes of the `y` coordinate of the public key 103 | 104 | - **Output data:** 105 | - If the signature verification process succeeds, it returns 1 in 32 bytes format. 106 | - If the signature verification process fails, it does not return any output data. 107 | 108 | ### Precompiled Contract Gas Usage 109 | 110 | The use of signature verification cost by `P256VERIFY` is `3450` gas. Following reasons and calculations are provided in the [Rationale](#rationale) and [Test Cases](#test-cases) sections. 111 | 112 | ## Rationale 113 | 114 | “secp256r1” ECDSA signatures consist of `v`, `r`, and `s` components. While the `v` value makes it possible to recover the public key of the signer, most signers do not generate the `v` component of the signature since `r` and `s` are sufficient for verification. In order to provide an exact and more compatible implementation, verification is preferred over recovery for the precompile. 115 | 116 | Existing P256 implementations verify `(x, y, r, s)` directly. We've chosen to match this style here, encoding each argument for the EVM as a `uint256`. 117 | 118 | This is different from the `ecrecover` precompiled address specification. The advantage is that it 1. follows the NIST specification (as defined in NIST FIPS 186-5 Digital Signature Standard (DSS)), 2. matches the rest of the (large) P256 ecosystem, and most importantly 3. allows execution clients to use existing well-vetted verifier implementations and test vectors. 119 | 120 | Another important difference is that the NIST FIPS 186-5 specification does not include a malleability check. We've matched that here in order to maximize compatibility with the large existing NIST P-256 ecosystem. 121 | 122 | Wrapper libraries **SHOULD** add a malleability check by default, with functions wrapping the raw precompile call (exact NIST FIPS 186-5 spec, without malleability check) clearly identified. For example, `P256.verifySignature` and `P256.verifySignatureWithoutMalleabilityCheck`. Adding the malleability check is straightforward and costs minimal gas. 123 | 124 | The `PRECOMPILED_ADDRESS` is chosen as `0x100` as `P256VERIFY` is the first precompiled contract presented as an RIP, and the address is the first available address in the precompiled address set that is reserved for the RIP precompiles. 125 | 126 | The gas cost is proposed by comparing the performance of the `P256VERIFY` and the `ECRECOVER` precompiled contract which is implemented in the EVM at `0x01` address. It is seen that “secp256r1” signature verification is ~15% slower (elaborated in [test cases](#test-cases)) than “secp256k1” signature recovery, so `3450` gas is proposed by comparison which causes similar “mgas/op” values in both precompiled contracts. 127 | 128 | ## Backwards Compatibility 129 | 130 | No backward compatibility issues found as the precompiled contract will be added to `PRECOMPILED_ADDRESS` at the next available address in the precompiled address set. 131 | 132 | ## Test Cases 133 | 134 | Functional tests are applied for multiple cases in the [reference implementation](#reference-implementation) of `P256VERIFY` precompiled contract and they succeed. Benchmark tests are also applied for both `P256VERIFY` and `ECRECOVER` with some pre-calculated data and signatures in the “go-ethereum”s precompile testing structure to propose a meaningful gas cost for the “secp256r1” signature verifications by the precompiled contract implemented in the [reference implementation](#reference-implementation). The benchmark test results by example data in the assets can be checked: 135 | 136 | - [P256Verify Benchmark Test Results](../assets/rip-7212/p256Verify_benchmark_test) 137 | - [Ecrecover Benchmark Test Results](../assets/rip-7212/ecrecover_benchmark_test) 138 | 139 | ``` 140 | # results of geth benchmark tests of 141 | # ECRECOVER and P256VERIFY (reference implementation) 142 | # by benchstat tool 143 | 144 | goos: darwin 145 | goarch: arm64 146 | pkg: github.com/ethereum/go-ethereum/core/vm 147 | │ compare_p256Verify │ compare_ecrecover │ 148 | │ sec/op │ sec/op │ 149 | PrecompiledP256Verify/p256Verify-Gas=3450-8 57.75µ ± 1% 150 | PrecompiledEcrecover/-Gas=3000-8 50.48µ ± 1% 151 | geomean 57.75µ 50.48µ 152 | 153 | │ compare_p256Verify │ compare_ecrecover │ 154 | │ gas/op │ gas/op │ 155 | PrecompiledP256Verify/p256Verify-Gas=3450-8 3.450k ± 0% 156 | PrecompiledEcrecover/-Gas=3000-8 3.000k ± 0% 157 | geomean 3.450k 3.000k 158 | 159 | │ compare_p256Verify │ compare_ecrecover │ 160 | │ mgas/s │ mgas/s │ 161 | PrecompiledP256Verify/p256Verify-Gas=3450-8 59.73 ± 1% 162 | PrecompiledEcrecover/-Gas=3000-8 59.42 ± 1% 163 | geomean 59.73 59.42 164 | 165 | │ compare_p256Verify │ compare_ecrecover │ 166 | │ B/op │ B/op │ 167 | PrecompiledP256Verify/p256Verify-Gas=3450-8 1.523Ki ± 0% 168 | PrecompiledEcrecover/-Gas=3000-8 800.0 ± 0% 169 | geomean 1.523Ki 800.0 170 | 171 | │ compare_p256Verify │ compare_ecrecover │ 172 | │ allocs/op │ allocs/op │ 173 | PrecompiledP256Verify/p256Verify-Gas=3450-8 33.00 ± 0% 174 | PrecompiledEcrecover/-Gas=3000-8 7.000 ± 0% 175 | geomean 33.00 7.000 176 | 177 | ``` 178 | 179 | ## Reference Implementation 180 | 181 | Implementation of the `P256VERIFY` precompiled contract is applied to go-ethereum client to create a reference. Also, a “secp256r1” package has already been included in the Besu Native library which is used by Besu client. Other client implementations are in the future roadmap. 182 | 183 | ## Security Considerations 184 | 185 | The changes are not directly affecting the protocol security, it is related with the applications using `P256VERIFY` for the signature verifications. The “secp256r1” curve has been using in many other protocols and services and there is not any security issues in the past. 186 | 187 | 188 | ## Copyright 189 | 190 | Copyright and related rights waived via [CC0](../LICENSE.md). 191 | -------------------------------------------------------------------------------- /RIPS/rip-7560.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7560 3 | title: Native Account Abstraction 4 | description: An account abstraction proposal that introduces consensus-layer protocol changes, instead of relying on higher-layer infrastructure. 5 | author: Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn) 6 | discussions-to: https://ethereum-magicians.org/t/rip-7560-native-account-abstraction/16664 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2023-09-01 11 | requires: 7702 12 | --- 13 | 14 | ## Abstract 15 | 16 | Combining the [EIP-2938](https://eips.ethereum.org/EIPS/eip-2938) 17 | and [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) 18 | into a comprehensive Native Account Abstraction proposal. 19 | 20 | We propose splitting the Ethereum transaction scope into multiple steps: validations, execution, 21 | and post-transaction logic. 22 | Transaction validity is determined by the result of the validation steps of a transaction. 23 | 24 | We further separate transaction validation for the purposes of authorization and the gas fee payment, 25 | allowing contract B to pay gas for a transaction that will be executed from account contract A. 26 | 27 | The benefits are in backward compatibility with the emerging ERC-4337 ecosystem while achieving the 28 | long-term goal of Native Account Abstraction. 29 | 30 | ## Motivation 31 | 32 | ERC-4337 can do a lot as a purely voluntary ERC. However, any of the out-of-protocol ways of achieving 33 | Account Abstraction faces several drawbacks compared to native support. There are a few key areas where 34 | it is weaker than a truly in-protocol solution: 35 | 36 | * Extra gas overhead of ~42k for a basic `UserOperation` compared to ~21k for a basic transaction. 37 | 38 | * Less benefit from in-protocol censorship resistance techniques such as crLists, which target transactions 39 | and would miss `UserOperations`. 40 | 41 | * Relying on a significantly smaller set of participating nodes and non-standard RPC methods like 42 | `eth_sendRawTransactionConditional`. 43 | 44 | * Inability to use `tx.origin` or contracts that rely on it as it returns the meaningless address of a bundler. 45 | 46 | EIP-2938 defines a very mature alternative approach to Account Abstraction. However, it does not translate 47 | well to the architecture of ERC-4337 that is being used in production without any protocol changes. 48 | Therefore, the implementation of EIP-2938 will not benefit as much from the production experience gained by using 49 | ERC-4337 and from maintaining backward compatibility with it. 50 | 51 | There is also a possibility that at some point in the future, all EOAs on Ethereum will be replaced with pre-deployed 52 | smart contracts. This, however, is impossible without an addition of Native Account Abstraction to the protocol. 53 | 54 | ## Specification 55 | 56 | ### Constants 57 | 58 | | Name | Value | 59 | |------------------------|---------------------| 60 | | FORK_BLOCK | TBD | 61 | | AA_TX_TYPE | TBD | 62 | | AA_ENTRY_POINT | `address(7560)` | 63 | | AA_SENDER_CREATOR | `address(ffff7560)` | 64 | | AA_BASE_GAS_COST | 15000 | 65 | | VERSION | 1 | 66 | | MAX_CONTEXT_SIZE | 65536 | 67 | | MAX_REVERT_REASON_SIZE | 1024 | 68 | 69 | 70 | ### Definitions 71 | 72 | * *Transaction*: 73 | An action initiated by an account and represented by a set of input parameters. 74 | This action will change the state of the Ethereum blockchain when it is included in a block. 75 | * *RIP-7560 Transaction*: 76 | An action initiated by a Smart Contract Account and represented with 77 | an [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) compatible Transaction Envelope object. 78 | * *RIP-7560 Call Frame*: 79 | A single atomic element of EVM code execution, 80 | represented by a single top-level call to a specific address with a given data. 81 | An RIP-7560 call frame may contain inner call frames as well, but they are not referred to as "RIP-7560 call frames". 82 | An RIP-7560 call frame may either succeed or revert. 83 | * *RIP-7560 Transaction Phase*: 84 | A set of RIP-7560 Call Frames that form a single step in an RIP-7560 Transaction flow. 85 | There are two phases in an RIP-7560 Transaction: *validation* and *execution*. 86 | * *Paymaster*: 87 | A smart contract whose sole role in an RIP-7560 Transaction is to pay for its gas. 88 | 89 | ### New Transaction Type 90 | 91 | A new [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) transaction with type AA_TX_TYPE is introduced. 92 | Transactions of this type are referred to as 93 | "AA transactions". Their payload should be interpreted as: 94 | 95 | ``` 96 | 97 | AA_TX_TYPE || rlp([ 98 | chainId, 99 | nonceKey, nonceSequence, 100 | sender, senderValidationData, 101 | deployer, deployerData, 102 | paymaster, paymasterData, 103 | executionData, 104 | builderFee, 105 | maxPriorityFeePerGas, maxFeePerGas, 106 | validationGasLimit, paymasterValidationGasLimit, paymasterPostOpGasLimit 107 | callGasLimit, 108 | accessList, 109 | authorizationList 110 | ]) 111 | 112 | ``` 113 | 114 | ``` 115 | authorizationList = [[chain_id, address, nonce, y_parity, r, s], ...] 116 | ``` 117 | 118 | 119 | The base gas cost of this transaction is set to `AA_BASE_GAS_COST` instead of 21000 to reflect the lack of "intrinsic" 120 | ECDSA signature verification. 121 | 122 | The `authorizationList` parameter has the exact same behaviour as defined by the 123 | [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). 124 | 125 | ### Definition of the RIP-7560 Transaction: 126 | 127 | The following table represents a full list of fields of an RIP-7560 transaction: 128 | 129 | | Name | Type | Description | 130 | |-------------------------------|----------------|-------------------------------------------------------------------------------------| 131 | | sender | DATA, 20 Bytes | Address of the Smart Contract Account making the transaction | 132 | | deployer | DATA, 20 Bytes | Address of the Deployer - account factory contract (optional) | 133 | | deployerData | DATA | Data that is provided to the Deployer contract (if `deployer` is set) | 134 | | paymaster | DATA, 20 Bytes | Address of the Paymaster contract (optional) | 135 | | paymasterData | DATA | Data that is provided to the Paymaster contract (if `paymaster` is set) | 136 | | executionData | DATA | Data that is provided to the Account contract for execution | 137 | | nonceKey | QUANTITY | A 192 bit nonce key. Use of `nonceKey != 0` is defined in RIP-7712. | 138 | | nonceSequence | QUANTITY | A 64 bit nonce sequence. Use of `nonceKey != 0` is defined in RIP-7712. | 139 | | builderFee | QUANTITY | Value passed from sender or paymaster to the `coinbase` | 140 | | maxPriorityFeePerGas | QUANTITY | The maximum gas price to be included as a tip to the validator | 141 | | maxFeePerGas | QUANTITY | The maximum fee per unit of gas | 142 | | validationGasLimit | QUANTITY | Gas provided for the transaction account validation frame | 143 | | paymasterValidationGasLimit | QUANTITY | Gas provided for the transaction paymaster validation frame (if `paymaster` is set) | 144 | | paymasterPostOpGasLimit | QUANTITY | Gas provided for the transaction paymaster `postOp` frame (if `paymaster` is set) | 145 | | callGasLimit | QUANTITY | Gas provided for the transaction RIP-7560 execution call frame | 146 | | accessList | OBJECT | An EIP-2930 compatible Access List structure | 147 | | authorizationsList | ARRAY | An EIP-7702 compatible list of contracts injected into EOAs | 148 | | authorizationData | DATA | Data that will be used by the Account to verify transaction | 149 | 150 | ### Definition of the RIP-7560 Transaction Receipt: 151 | 152 | A transaction receipt object shape is modified to support the RIP-7560 transaction receipts. 153 | 154 | | Name | Type | Description | 155 | |------------------------------|------------------|--------------------------------------------------------------------------------------------------------------------------------------| 156 | | sender | DATA, 20 Bytes | Address of the sender of this transaction | 157 | | paymaster | DATA, 20 Bytes | Address of the Paymaster if it is paying for the transaction, `null` otherwise | 158 | | deployer | DATA, 20 Bytes | Address of the Deployer if it is included in the transaction, `null` otherwise | 159 | | senderCreationGasUsed | QUANTITY | The amount of gas actually used by the sender deployment frame, or zero if frame not executed | 160 | | senderValidationGasUsed | QUANTITY | The amount of gas actually used by the sender validation frame | 161 | | paymasterValidationGasUsed | QUANTITY | The amount of gas actually used by the paymaster validation frame, or zero if frame not executed | 162 | | executionGasUsed | QUANTITY | The amount of gas actually used by the RIP-7560 execution call frame | 163 | | postOpGasUsed | QUANTITY | The amount of gas actually used by the paymaster `postOp` frame, or zero if frame not executed | 164 | | executionStatus | QUANTITY | 0 (success), 1 (execution reverted), 2 (`postOp` reverted), 3 (both execution and `postOp` reverted) status of the execution frame | 165 | | validationLogs | ARRAY | Array of log objects, which this transaction'S VALIDATION FRAME generated. | 166 | | transactionHash | DATA, 32 Bytes | Hash of the transaction. | 167 | | transactionIndex | QUANTITY | Integer of the transactions index position in the block. | 168 | | blockHash | DATA, 32 Bytes | Hash of the block where this transaction was in. | 169 | | blockNumber | QUANTITY | Block number where this transaction was in. | 170 | | cumulativeGasUsed | QUANTITY | The total amount of gas used when this transaction was executed in the block. | 171 | | effectiveGasPrice | QUANTITY | The sum of the base fee and tip paid per unit of gas. | 172 | | gasUsed | QUANTITY | The amount of gas used by this specific transaction alone. | 173 | | logs | ARRAY | Array of log objects, which this transaction'S EXECUTION FRAME generated. | 174 | | logsBloom | DATA, 256 Bytes | Bloom filter for light clients to quickly retrieve related logs. | 175 | | type | QUANTITY | Integer of the transaction type | 176 | 177 | ### Gas fees are charged directly from the contract balance 178 | 179 | The maximum gas cost of the `AA_TX_TYPE` transaction is defined as: 180 | 181 | ``` 182 | 183 | maxPossibleGasCost = AA_BASE_GAS_COST + 184 | validationGasLimit + 185 | paymasterValidationGasLimit + 186 | callGasLimit + 187 | paymasterPostOpGasLimit 188 | 189 | ``` 190 | 191 | If `paymaster` is not specified, the `maxPossibleGasCost` is charged up-front, before any computation is done in any 192 | execution frame, from the balance of the `sender` address. 193 | If `paymaster` is specified, the gas cost is charged from its balance. 194 | The transaction is invalid if the balance of the account that is being pre-charged, 195 | whether it is a `sender` or a `paymaster`, is insufficient. 196 | After the transaction finishes its execution, the address that was pre-charged may receive a gas refund. 197 | 198 | The meanings of the `maxPriorityFeePerGas` and `maxFeePerGas` are unchanged from how they are defined in the 199 | [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). 200 | 201 | ### Gas fees charged for transaction input 202 | 203 | For all the existing transaction types, G_txdatazero (4 gas) and G_txdatanonzero (16 gas) per byte is 204 | charged for the `data` parameter. 205 | 206 | Transaction Type AA_TX_TYPE introduces the following dynamic length inputs: `executionData`, `paymasterData`, 207 | `deployerData`, `authorizationData`. Each of these parameters' gas cost is counted towards transaction data cost. 208 | This transaction data gas cost is referred to as `calldataGasUsed` and is subtracted from the `validationGasLimit` 209 | before execution of the transaction. 210 | The transaction is considered INVALID if `validationGasLimit` is smaller than `calldataGasUsed`. 211 | 212 | ### Builder Fee 213 | 214 | As we need to account for an additional off-chain work that block builders have to perform to 215 | include `AA_TX_TYPE` transactions in their blocks, as well as a potential L1 gas cost for builders 216 | operating on L2 rollups, and given that this work does not correspond to the amount of gas spent on 217 | validation and is not linked to the gas price, the `sender` may decide 218 | to pay an extra `builderFee` as a "tip" to the block builder. 219 | 220 | This value is denominated in wei and is passed from the `sender`, or the `paymaster` if it is specified, 221 | to the `coinbase` of the current block as part of the gas pre-charge. 222 | 223 | ### Multiple execution frames for a single transaction 224 | 225 | All existing transaction types only have an implicit validation phase where balance, nonce, and signature are checked, 226 | and a single top-level execution frame with 227 | `tx.origin == msg.sender` which is the address that is determined by a transaction ECDSA signature. 228 | 229 | When processing a transaction of type `AA_TX_TYPE`, however, multiple execution frames will be created. 230 | The full list of possible frames tries to replicate the ERC-4337 flow: 231 | 232 | 1. Validation Phase 233 | * `sender` deployment frame (once per account) 234 | * `sender` validation frame (required) 235 | * `paymaster` validation frame (optional) 236 | 2. Execution Phase 237 | * `sender` execution frame (required) 238 | * `paymaster` post-transaction frame (optional) 239 | 240 | All execution frames in the "Validation Phase" must be completed successfully without reverting, and 241 | both `sender` and `paymaster` validation frames must include a call to a corresponding `AA_ENTRY_POINT` 242 | approval callback functions 243 | in order for the transaction to be considered valid for a given position in a block. 244 | 245 | In all top-level frames, the global variables have the following meaning: 246 | 247 | | Opcode Name | Solidity Equivalent | Value | 248 | |-------------|---------------------|-------------------------------------------------------------------------------| 249 | | `CALLER` | `msg.sender` | The `AA_ENTRY_POINT` address. `AA_SENDER_CREATOR` for the "deployment frame". | 250 | | `ORIGIN` | `tx.origin` | The transaction `sender` address | 251 | | `CALLDATA*` | `msg.data` | The transaction data is set to inputs of the corresponding frame | 252 | 253 | ### Transaction execution context 254 | 255 | Note that some behaviours in the EVM depend on the transaction context. These behaviours are: 256 | 1. Costs of the SSTORE opcode per [EIP-2200](../eip-2200) 257 | 2. Costs of accessing cold addresses and slots per [EIP-2929](../eip-2929) 258 | 3. Values available within the transient storage per [EIP-1163](../eip-1163) 259 | 4. Maximum amount of gas refund assigned after the execution per [EIP-3529](../eip-3529) 260 | 5. Availability of the SELFDESTRUCT opcode per [EIP-6780](../eip-6780) 261 | 262 | These features are not affected by the separation of the transaction into multiple frames. 263 | Meaning, for example, that a value set with TSTORE in one frame will remain available in the next one. 264 | 265 | #### Sender deployment frame 266 | 267 | The `deployer` address is invoked with the `deployerData` as call data input from the `AA_SENDER_CREATOR` address. 268 | 269 | The gas limit of this frame is set to `validationGasLimit`. 270 | The amount of gas used by this frame is referred to as `senderCreationGasUsed`. 271 | 272 | The sender deployment frame MUST result in the `sender` address becoming 273 | initialized with contract code. 274 | 275 | #### Sender validation frame 276 | 277 | We define the following Solidity struct to represent the AA transaction on-chain: 278 | 279 | ```solidity 280 | 281 | struct TransactionTypeRIP7560 { 282 | address sender; 283 | address paymaster; 284 | address deployer; 285 | uint256 nonceKey; 286 | uint256 nonceSequence; 287 | uint256 builderFee; 288 | uint256 maxFeePerGas; 289 | uint256 maxPriorityFeePerGas; 290 | uint256 validationGasLimit; 291 | uint256 paymasterValidationGasLimit; 292 | uint256 paymasterPostOpGasLimit; 293 | uint256 callGasLimit; 294 | bytes senderValidationData; 295 | bytes paymasterData; 296 | bytes deployerData; 297 | bytes executionData; 298 | Authorization[] authorizationsList; 299 | } 300 | 301 | struct Authorization { 302 | uint256 chainId; 303 | address delegate; 304 | uint256 nonce; 305 | uint8 yParity; 306 | uint256 r; 307 | uint256 s; 308 | } 309 | 310 | ``` 311 | 312 | We then define the following Solidity method and the `sender` of the transaction is invoked with the corresponding data: 313 | 314 | ```solidity 315 | 316 | function validateTransaction(uint256 version, bytes32 txHash, bytes transaction) external; 317 | 318 | ``` 319 | 320 | The gas limit of this frame is set to `validationGasLimit - senderCreationGasUsed - calldataGasUsed`.\ 321 | The `transaction` parameter is interpreted as an ABI encoding of `TransactionTypeRIP7560`.\ 322 | The `txHash` parameter represents the hash of the AA_TX_TYPE transaction with empty `authorizationData`, 323 | as defined in section 324 | [Calculation of Transaction Type AA_TX_TYPE hash](#calculation-of-transaction-type-aatxtype-hash).\ 325 | The `version` parameter is added in order to maintain the Solidity method ID in case of changes to this struct 326 | in future revisions of this EIP. 327 | 328 | The amount of gas used by this frame is referred to as `senderValidationGasUsed`. 329 | 330 | We then define the following Solidity methods as an `AA_ENTRY_POINT` approval callback function: 331 | 332 | ```solidity 333 | function acceptAccount(uint256 validAfter, uint256 validUntil) external; 334 | ``` 335 | 336 | ```solidity 337 | function sigFailAccount(uint256 validAfter, uint256 validUntil) external; 338 | ``` 339 | 340 | Calls to the `AA_ENTRY_POINT` approval callbacks have the following meaning: 341 | 342 | - `acceptAccount` - This callback is called by the account after it verified the transaction and agreed to pay for its execution. 343 | - `sigFailAccount` - This callback is called by the account if the transaction is syntactically valid, 344 | but the `authorizationData` is incorrect.\ 345 | Note that this callback is used during gas estimation and does **not** indicate a valid transaction. 346 | 347 | The parameters passed to the callback functions have the following meaning: 348 | 349 | - **validAfter** - a timestamp. The transaction is valid only after this time. 350 | - **validUntil** - a timestamp. The transaction is valid only up to this time. Zero is a special value meaning "valid indefinitely". 351 | 352 | The account MUST make exactly one call to the `AA_ENTRY_POINT` to be considered valid. 353 | Any other outcome, such as the account not making any calls to the `AA_ENTRY_POINT` callbacks, 354 | making any call other than `acceptAccount`, 355 | making multiple calls to the `AA_ENTRY_POINT`, 356 | or causing a reverted execution is considered to fail validation, 357 | and the transaction is rejected and not included on-chain. 358 | 359 | These callbacks may be called either by the account directly or inside a `DELEGATECALL` that runs in the context of the account. 360 | If a callback is called in the context of any other contract during the validation frame, the transaction is rejected and not included on-chain. 361 | 362 | #### Paymaster validation frame 363 | 364 | The `paymaster` of the transaction, if specified, is invoked with the following data: 365 | 366 | ```solidity 367 | function validatePaymasterTransaction(uint256 version, bytes32 txHash, bytes transaction) external; 368 | ``` 369 | 370 | The gas limit of this frame is set to `paymasterValidationGasLimit`. 371 | 372 | The amount of gas used by this frame is referred to as `paymasterValidationGasUsed`. 373 | 374 | - The `version` parameter is `VERSION` 375 | - The `transaction` parameter is interpreted as an ABI encoding of `TransactionTypeRIP7560`.\ 376 | - The `txHash` parameter represents the hash of the AA_TX_TYPE transaction with empty `authorizationData`, 377 | as defined in section 378 | [Calculation of Transaction Type AA_TX_TYPE hash](#calculation-of-transaction-type-aatxtype-hash). 379 | 380 | 381 | We then define the following Solidity methods as an `AA_ENTRY_POINT` approval callback function: 382 | 383 | ```solidity 384 | function acceptPaymaster(uint256 validAfter, uint256 validUntil, bytes context); 385 | ``` 386 | 387 | ```solidity 388 | function sigFailPaymaster(uint256 validAfter, uint256 validUntil, bytes context); 389 | ``` 390 | 391 | Calls to the `AA_ENTRY_POINT` approval callbacks have the following meaning: 392 | 393 | - `acceptPaymaster` - This callback is called by the paymaster after it verified the transaction and agrees to pay for its execution. 394 | - `sigFailPaymaster` - This callback is called by the paymaster if its `paymasterData` is expected to contain 395 | some kind of signature, but it does not contain a valid one.\ 396 | Note that this callback is used during gas estimation and does **not** indicate a valid transaction. 397 | 398 | The parameters passed to the callback functions have the following meaning: 399 | 400 | - `validAfter`, `validUntil` - same as defined in `acceptAccount` 401 | - `context` - optional byte array provided by the paymaster contract, which is later passed to `postPaymasterTransaction`. 402 | The length of this value MUST NOT exceed `MAX_CONTEXT_SIZE` bytes. 403 | 404 | 405 | The paymaster MUST make exactly one call to the `AA_ENTRY_POINT` to be considered valid. 406 | Any other outcome, such as the paymaster not making any calls to the `AA_ENTRY_POINT` callbacks, 407 | making any call other than `acceptPaymaster`, 408 | making multiple calls to the `AA_ENTRY_POINT`, 409 | or causing a reverted execution is considered to fail validation, 410 | and the transaction is rejected and not included on-chain. 411 | 412 | These callbacks may be called either by the paymaster directly or inside a `DELEGATECALL` that runs in the context of the paymaster. 413 | If a callback is called by any other contract during the validation frame, the transaction is rejected and not included on-chain. 414 | 415 | #### Sender execution frame 416 | 417 | The `sender` address is invoked with `executionData` input. 418 | 419 | The gas limit of this frame is set to `callGasLimit`.\ 420 | Calculation of the `calldataGasUsed` value is defined in the 421 | [Gas fees charged for transaction input](#gas-fees-charged-for-transaction-input) section.\ 422 | The amount of gas used by this frame is referred to as `gasUsedByExecution`. 423 | 424 | The validation frames do not revert even if the execution frame reverts. 425 | The `postPaymasterTransaction` may still be called with a `success: false` flag. 426 | 427 | #### Paymaster post-transaction frame 428 | 429 | After the sender execution frame is over the `paymaster` may need to perform some post-transaction logic, 430 | for instance to perform some kind of cleanup or bookkeeping. 431 | If the gas payment validation frame provided a non-zero `context` in the `acceptPaymaster` callback, 432 | the `paymaster` is invoked again with the following inputs: 433 | 434 | ```solidity 435 | 436 | function postPaymasterTransaction(bool success, uint256 actualGasCost, bytes context) external; 437 | 438 | ``` 439 | 440 | - `success` indicates whether this transaction's execution frame completed without revert. 441 | - `actualGasCost` parameter is the actual amount of gas spent by the paymaster for this transaction up to this point. Note that it does not include the gas cost of the `postPaymasterTransaction` function itself. 442 | 443 | The gas limit of this frame is set to `paymasterPostOpGasLimit`. 444 | 445 | Revert in the `postPaymasterTransaction` frame reverts the transaction's execution frame as well. 446 | The gas fees charged from the `paymaster` will include the validation frames and also gas cost of the reverted execution frame and postPaymasterTransaction frame. 447 | 448 | ### Execution flow diagram 449 | 450 | The execution flow determined by an Account Abstraction Transaction is visualised by the following flow diagram: 451 | 452 | ![](../assets/rip-7560/flow_diagram.png) 453 | *Execution flow for the Native Account Abstraction Transactions* 454 | 455 | ### Execution layer transaction validation 456 | 457 | On the execution layer, the transaction validity conditions for a block are extended as follows: 458 | 459 | ```go 460 | 461 | func validateAccountAbstractionTransaction(tx *Transaction) { 462 | assert !(sender.code.length > 0 && deployer != address(0)) 463 | 464 | if (sender.code.length == 0 && deployer != address(0)) { 465 | calldataGasUsed := calculateCallDataGasUsed(tx) 466 | retDeployer, error := evm.Call( 467 | from: AA_SENDER_CREATOR, 468 | to: deployer, 469 | input: deployerData, 470 | gas: validationGasLimit - calldataGasUsed) 471 | assert error == nil 472 | assert sender.code.length > 0 473 | } 474 | 475 | senderInput := ABI.encodeWithSelector('validateTransaction', tx, tx.hash); 476 | callbackParamsSender, error := evm.Call( 477 | from: AA_ENTRY_POINT, 478 | to: sender, 479 | input: senderInput, 480 | gas: validationGasLimit - retDeployer.gasUsed) 481 | assert error == nil 482 | assert callbackParamsSender != nil 483 | assert Date.now() <= callbackParamsSender.validUntil 484 | assert Date.now() >= callbackParamsSender.validAfter 485 | assert callbackParamsSender.isValidAuthorizationData 486 | 487 | if (paymaster != address(0)) { 488 | paymasterInput := ABI.encodeWithSelector('validatePaymasterTransaction', tx, tx.hash) 489 | callbackParamsPaymaster, error := evm.Call( 490 | from: AA_ENTRY_POINT, 491 | to: paymaster, 492 | input: paymasterInput, 493 | gas: paymasterValidationGasLimit) 494 | assert error == nil 495 | assert callbackParamsPaymaster != nil 496 | assert Date.now() <= callbackParamsPaymaster.validUntil 497 | assert Date.now() >= callbackParamsPaymaster.validAfter 498 | assert callbackParamsPaymaster.isValidAuthorizationData 499 | } 500 | } 501 | 502 | ``` 503 | 504 | In order to defend from DoS attack vectors, the block builders SHOULD consider 505 | the opcode banning and storage access rules described in [ERC-7562](https://eips.ethereum.org/EIPS/eips/eip-7562). 506 | 507 | [Block validation](#execution-layer-block-validation) takes roughly the same amount of work as without AA transactions. 508 | In any case, validation must execute the entire block in order to verify the state change. 509 | During this execution, it currently verifies signatures, nonces, and gas payment. 510 | With Account Abstraction, it will also verify that all the validation frames were successful. 511 | There is a slight increase in required memory mostly used to store the `context` value that is passed from 512 | the `paymaster` validation frame to its post-transaction frame. 513 | 514 | As long as all transaction validation steps execute successfully and provide correct values 515 | to their `AA_ENTRY_POINT` callbacks, the block is considered valid. 516 | Block builders who are willing to relax the rules applied to the validation frames MAY do so. 517 | 518 | ### Transaction flow diagram 519 | 520 | Zooming into a single transaction, the validation part of an AA transaction may include multiple execution frames: 521 | 522 | ![](../assets/rip-7560/zoom_into_transaction.png) 523 | *Frames within a single Native Account Abstraction Transaction within a block* 524 | 525 | ### Transaction validity time range parameters 526 | 527 | The `Paymaster validation frame` and the `Sender validation frame` each provide values for `validUntil` and `validAfter`. 528 | 529 | These values allow the `sender` and `paymaster` contracts to specify 530 | a time range for the blocks the transaction will be valid for. 531 | 532 | Transaction cannot be included in a block outside of this time range. 533 | If included, such a block is considered invalid. 534 | 535 | Passing `validUntil = 0` and `validAfter = 0` disables the check. 536 | 537 | ### Calculation of Transaction Type AA_TX_TYPE hash 538 | 539 | ``` 540 | 541 | keccak256(AA_TX_TYPE || rlp(transaction_payload) 542 | 543 | ``` 544 | 545 | Note that the `chainId` and `accessList` parameters are included in the transaction hash 546 | calculation but are not available on-chain as part of the `TransactionTypeRIP7560` struct. 547 | 548 | In order to calculate the transaction hash that will be used during the signing of the transaction and validation of 549 | the transaction signature by the `sender`, the value of the `authorizationData` parameter is considered to be an empty 550 | byte array. 551 | 552 | ## Rationale 553 | 554 | ### Using Solidity method selectors in a Core EIP 555 | 556 | The contracts that have a role in this Account Abstraction proposal, such as `sender` or `paymaster`, 557 | MUST know which code to execute and understand the calldata provided to them in order to validate the transaction. 558 | 559 | We argue that the most straightforward implementation is to rely on Solidity 4-byte method selectors as it is an 560 | established de-facto standard. 561 | 562 | ### Calling the `deployer` from the `AA_SENDER_CREATOR` address 563 | 564 | It is important that the `deployer` is **not** invoked from the `AA_ENTRY_POINT` but from the `AA_SENDER_CREATOR`. 565 | 566 | This is necessary to guarantee that `AA_ENTRY_POINT` may never initiate a call to a `sender` execution function 567 | without first completing a successful validation. 568 | Without this protection, as we do not control the `deployerData` field, it may be constructed to look like 569 | a legitimate call from the `AA_ENTRY_POINT` to the `sender`. 570 | 571 | ### Usage of `AA_ENTRY_POINT` approval callbacks 572 | 573 | The successful validation frame execution in the context of a smart contract leads to a transaction gas payment. 574 | It is important to prevent any unsuspecting contract from being tricked into "accepting" an 575 | RIP-7560 transaction validation, which may lead to this contract being drained. 576 | 577 | To do so we require specific call to the `AA_ENTRY_POINT` address to indicate RIP-7560 transaction acceptance. 578 | 579 | ### The Usage of `sigFailAccount` and `sigFailPaymaster` for `authorizationData` check failure 580 | 581 | This callback is called by an account or a paymaster during their respective validation frames if they can verify 582 | all relevant details of the transaction except for the transaction `authorizationData`. 583 | 584 | This callback is used during gas estimation, and it helps wallet and apps to determine the gas used by the validation 585 | process before generating any real signatures.\ 586 | The transaction is expected to consume the same amount of gas when updated with a valid `authorizationData`. 587 | 588 | ## Backwards Compatibility 589 | 590 | This EIP preserves most of the design elements established by the ERC-4337. This allows the same client code and smart 591 | contracts to be used in both systems with minimal to no modifications, while providing significant UX improvements. 592 | 593 | Existing contracts are not significantly affected by the change. 594 | The assumption that `tx.origin` is guaranteed to be an EOA is no longer valid. 595 | The assumption that `tx.origin` is the address that pays for the current transaction is no longer valid as well. 596 | 597 | Any code that expects a single top-level execution frame for an Ethereum transaction will have to accommodate 598 | the new transaction type. 599 | 600 | [EIP-3607](https://eips.ethereum.org/EIPS/eip-3607) introduces a ban on transactions from senders with deployed code. 601 | This limitation does not apply to AA_TX_TYPE transactions. 602 | 603 | ### Migration path for existing ERC-4337 projects and further roadmap 604 | 605 | #### Existing bundlers can co-exist on the network 606 | 607 | The ERC-4337 is not a protocol change and may remain operational in parallel to this EIP indefinitely. 608 | Given the similarity to ERC-4337, the same block builders may easily support both ERC-4337 and `AA_TX_TYPE` transactions. 609 | 610 | #### Accounts need to upgrade their `EntryPoint` to an adapter contract 611 | 612 | The team behind ERC-4337 will provide a reference implementation of a contract converting 613 | the ABI of the `paymaster` and `sender` contracts. This adapter can be set as a trusted 614 | `EntryPoint` address by the ERC-4337 contracts. 615 | 616 | #### Supporting ERC-4337 RPC calls as a compatibility layer 617 | 618 | The `sender` contracts MAY support both ERC-4337 and `AA_TX_TYPE` transactions during a transition period, 619 | as long as this EIP may be adopted by some chains and not by others. 620 | 621 | ## Security Considerations 622 | 623 | This EIP creates a complex and sophisticated mechanism and aims to expand the usage of Smart Contract Accounts. 624 | All of it creates a lot of new risk vectors and attack surfaces. 625 | 626 | The following is a non-exhaustive list of known security considerations regarding Native Account Abstraction. 627 | 628 | ### Directly charging the balance of a contract 629 | 630 | This EIP adds a new way for a smart contract to have its balance charged simply by making a valid callback call 631 | to the `AA_ENTRY_POINT` address from a 632 | function with method ID that corresponds to `validateTransaction`, `validatePaymasterTransaction`. 633 | 634 | This creates a new kind of risk for contracts that accidentally or maliciously contain such methods but are not public 635 | about the fact that these contracts can be used as a `sender` or a `paymaster` in an `AA_TX_TYPE` transaction. 636 | 637 | This concern is mitigated by requiring these contracts to call `acceptAccount` or `acceptPaymaster` callbacks 638 | on the `AA_ENTRY_POINT` address, which makes contracts' interaction with the `AA_ENTRY_POINT` address explicit. 639 | Code reviewers should be aware of this feature of RIP-7560 transactions. 640 | 641 | ### Observing revert reasons in a validation frame 642 | 643 | Existing transaction types get included in a block even if reverted and provide a revert reason for debugging purposes. 644 | There is a very short list of things that can cause a transaction not to be included on-chain: 645 | 646 | * low gas fee 647 | * insufficient balance 648 | * invalid nonce 649 | * censorship 650 | 651 | This is not the case for reverts that occur in the validation phase of an `AA_TX_TYPE` transaction. 652 | In order to address this developers should track the validity of these transactions being signed and are encouraged 653 | to rely on the `validUntil` time range parameter to guarantee a transaction that has not been included in the intended time 654 | will not become valid again unexpectedly for the user who had sent it. 655 | 656 | ### Denial of Service attacks on the block builder 657 | 658 | It is important to consider the ability of the block builder to fill the block with transactions in the allotted time. 659 | 660 | In terms of block validity, all validation and RIP-7560 execution call frames may read and write any state when included in the block. 661 | This means that transactions are technically able to invalidate each other. 662 | 663 | Block builders may face a risk of having multiple eligible 664 | transactions being invalidated by a single transaction once they include it in a block, causing the Denial of Service. 665 | Sequencer-like block builders do not have such a risk as long as they process incoming transactions 666 | in the order they are received. 667 | 668 | As part of the mitigation, the AA transactions SHOULD be bound by storage access rules to avoid 669 | DoS on block builders. 670 | These rules are defined in [ERC-7562](https://eips.ethereum.org/EIPS/eips/eip-7562). 671 | 672 | The full mitigation may be achieved by separating the validation from into a separate context as described in the 673 | [RIP-7711](./rip-7711.md). 674 | 675 | ### Atomic "validate and execute" fallback function 676 | 677 | We recommend that Smart Contract Account developers make sure that users will be able to control their accounts 678 | even in the event of `AA_TX_TYPE` transactions becoming unavailable for whatever reason. 679 | 680 | This can be easily achieved by providing a public function that includes calls to both the validation and execution 681 | handlers of the Smart Contract Account. 682 | 683 | ## Copyright 684 | 685 | Copyright and related rights waived via [CC0](../LICENSE.md). 686 | -------------------------------------------------------------------------------- /RIPS/rip-7614.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7614 3 | title: Expose call stack to contracts 4 | description: Implement a call stack to record opcodes, addresses and function selectors and expose through a precompiled contract. 5 | author: Caner Çıdam (@canercidam) , Jonathan Alexander (@jalex206) , Andrew Beal (@ajbealETH) , Ariel Tempelhof (@ArielTM) , Oren Fine (@orenfine) , Assaf Eli (@assafIronblocks) , Or Dadosh (@ordd) , Idan Levin , Alejandro Navarro (Grover-a5) 6 | discussions-to: https://ethereum-magicians.org/t/rip-expose-call-stack-to-contracts/18535 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2024-07-02 11 | --- 12 | 13 | ## Abstract 14 | 15 | Implement a call stack to record opcodes, addresses and function selectors and expose through a precompiled contract. If implemented, the precompile will give protocols deeper visibility into addresses involved at any point in execution. 16 | 17 | ## Motivation 18 | 19 | This proposal seeks to advance smart contract security in the Ethereum L2 ecosystem by enabling more robust exploit prevention solutions that depend on deeper visibility into the transaction call stack. 20 | 21 | Threat detection has advanced a lot in the last year. There are at least a dozen security projects focused on monitoring and exploit detection, and collectively they are proving that attackers can be identified in advance. Early detection hinges on being able to identify malicious smart contracts as soon as they are deployed on-chain using a combination of static and dynamic analysis. Once malicious contracts are flagged, protocols can screen incoming transactions and revert if they include one of these addresses. In parallel, anomaly detection - identifying transactions outside of normal user behavior - is also emerging as a legitimate approach to preventing exploits. Being able to consistently identify attackers and anomalies in advance opens the door to transaction screening, where protocols can choose to automatically revert transactions from high risk entities, or transactions that fall significantly outside "expected behavior". 22 | 23 | One technical challenge limiting the long-term effectiveness of transaction screening is address visibility. Today, a smart contract only has visibility into `msg.sender` and `tx.origin`, not the full call stack. An attacker can use various forms of proxies to "obfuscate" the true source of the call and circumvent detection. While these circumvention techniques are not being used today, we expect hackers to quickly adopt them once transaction screening becomes more pervasive. 24 | 25 | This proposal introduces a non-intrusive way to increase visibility into hackers' obfuscation techniques by keeping track of the call stack and exposing the latest list via an EVM precompiled contract when requested at any specific point of EVM execution. This helps the contracts screen more addresses and patterns before proceeding. 26 | 27 | ## Specification 28 | 29 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.html) and [RFC 8174](https://www.ietf.org/rfc/rfc8174.html). 30 | 31 | ### Constants 32 | 33 | | Name | Value | 34 | |----------------------------------|----------| 35 | | PRECOMPILE_ADDRESS | TBD | 36 | | CALL_STACK_PER_CALL_COST | 5 | 37 | | PRECOMPILE_BASE_GAS_COST | TBD | 38 | | PRECOMPILE_PER_CALL_COST | 2 | 39 | 40 | ### Call 41 | 42 | A Call is defined by an opcode, an address and a function selector. 43 | 44 | The selector MUST be the first four bytes of the call data for CALL-style opcodes, if call input is non-zero. For CREATE-style opcodes it MUST be an empty value. 45 | 46 | ### CallStack 47 | 48 | This is proposed as a new type of stack for client implementations to include and is based on the "message-call/contract-creation stack" mentioned in [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf). It is separate from the machine stack used for execution. 49 | 50 | CallStack MUST be initialized per transaction simulation, unlike how a new machine stack is initialized per call frame. 51 | 52 | All operations that create a new call frame MUST push a Call to the CallStack and MUST pop after the call frame has exited. In the Cancun hard fork specification, this list operations consists of `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`, `CREATE` and `CREATE2`. The initial transaction call frame MUST always be pushed as a Call when the transaction execution starts and must be popped when the execution finishes. 53 | 54 | ### Precompiled contract 55 | 56 | The call stack SHOULD implement the precompiled contract interface defined in the client implementation and MUST encode and return the contents of the call stack. 57 | 58 | The encoder logic MUST follow [Solidity Contract ABI Specification](https://docs.soliditylang.org/en/latest/abi-spec.html) to encode the list of Calls. While this provides an encoding standard and Solidity friendliness, it does not introduce any difficulty in supporting another language, since the encoded bytes are trivial to parse. 59 | 60 | The encoder MUST write each value as a 32-byte padded word as in below pseudocode: 61 | 62 | ``` 63 | let b: ByteArray 64 | 65 | b.append(0x20) // default offset 66 | b.append(len(CallStack)) 67 | 68 | for call in CallStack: 69 | b.append(call.Op) 70 | b.append(call.Address) 71 | b.append(call.Selector) 72 | ``` 73 | 74 | Assuming that the call stack has one call such as 75 | - Opcode: `CALL` (`0xf1`) 76 | - Address: `0xafafafafafafafafafafafafafafafafafafafaf` 77 | - Selector: `0xabcdef12` 78 | then the 32-byte words in the encoded output would be: 79 | ``` 80 | 0000000000000000000000000000000000000000000000000000000000000020 // default offset 81 | 0000000000000000000000000000000000000000000000000000000000000001 // call stack size 82 | 00000000000000000000000000000000000000000000000000000000000000f1 // CALL opcode 83 | 000000000000000000000000afafafafafafafafafafafafafafafafafafafaf // address 84 | 00000000000000000000000000000000000000000000000000000000abcdef12 // selector 85 | ``` 86 | 87 | Please note that the original output is a contiguous array and is not line-delimited. 88 | 89 | ### Gas costs 90 | 91 | #### Call stack gas cost 92 | 93 | The call stack implementation adds minimal and negligible overhead to EVM execution. Each call stack item is smaller than 32-byte words pushed to the machine stack. For these reasons, clients MAY charge transaction senders a total of `CALL_STACK_PER_CALL_COST` per Call pushed/popped to/from the CallStack. This value is chosen to follow the total cost of `PUSH1` and `POP`. Given that `CALL_STACK_PER_CALL_COST` is very small compared to costs of the opcodes listed in the [CallStack](#callstack) section, it is OPTIONAL to charge transaction senders with this amount. 94 | 95 | #### Precompiled contract gas cost 96 | 97 | ``` 98 | PRECOMPILE_BASE_GAS_COST + PRECOMPILE_PER_CALL_COST * len(CallStack) 99 | ``` 100 | 101 | Encoder overhead at the time of precompile execution is at a reasonable level when a reference implementation is benchmarked against readily available precompiled contracts. For this reason, `PRECOMPILE_BASE_GAS_COST` SHOULD be introduced to cover any base level overhead from encoding and the call stack. 102 | 103 | `PRECOMPILE_PER_CALL_COST` value SHOULD either be equal to or greater than the gas cost of `CALLER` and `ADDRESS` opcodes so that competition would be avoided if `PRECOMPILE_BASE_GAS_COST` was chosen as zero and when CallStack size is one. Having a per-call gas cost is also in line with scaling up the precompile cost with every call. 104 | 105 | ### Precompile call example 106 | 107 | ```solidity 108 | contract CallStack { 109 | address constant PRECOMPILE_ADDRESS = address(...); // TBD 110 | 111 | struct Call { 112 | uint8 opCode; 113 | address addr; 114 | uint32 selector; 115 | } 116 | 117 | function getCallStack() internal returns (Call[] memory) { 118 | (, bytes memory returndata) = address(PRECOMPILE_ADDRESS).call(bytes("")); 119 | Call[] memory calls = abi.decode(returndata, (Call[])); 120 | return calls; 121 | } 122 | } 123 | ``` 124 | 125 | ## Rationale 126 | 127 | ### Observing addresses beyond `tx.origin` and `msg.sender` 128 | 129 | This functionality is useful in determining the other contracts involved in a transaction up to the point of execution, between `tx.origin` and the latest `msg.sender`. 130 | 131 | Moreover, blackhats deploy attack contracts before launching the attack and that gives a time frame to scan and detect the malicious contract. If the attack transaction does a `DELEGATECALL` from a proxy to the attack contract, to call the victim contract, then the `msg.sender` observed by the victim contract is the proxy contract (and not the actual malicious attack contract). The call stack breaks this evasion by exposing the `DELEGATECALL`ed addresses in the call stack. 132 | 133 | ### Evasion concerns 134 | 135 | Logic exploits happen in the form of a malicious contract calling a victim contract, directly or indirectly, one or many times. Off-chain detection mechanisms are able to update on-chain risk/reputation oracles after analyzing deployed contracts. This means that, a screening solution that uses the call stack should ideally check each address either in a whitelist oracle _or_ check contract age and then check in a negative reputation oracle. Combined with such checks, any timing of attack contract deployment and attack transaction/call will not help an attacker evade on-chain detection and this proposal's aim to make extra visibility useful will succeed. However, please note that this proposal does not try to suggest or solve anything whatsoever about how such checks should be implemented since we intend to solve only the visibility disadvantage protocols have and would like to level protocols' transaction visibility with attackers. 136 | 137 | ### Account abstraction support 138 | 139 | By design, the call stack and the precompiled contract support the account abstraction outlined in [ERC-4337](https://ercs.ethereum.org/ERCS/erc-4337). 140 | 141 | In ERC-4337, UserOperations are calls to (non-EOA) smart wallets validated and bundled into a single transaction to be executed. In the reference implementations, each UserOperation is executed sequentially and isolated from each other. The call stack implementation maintains this isolation by not exposing addresses from one UserOperation to another. A smart wallet and any deeper callees are only exposed to the global singleton EntryPoint contract commonly with other UserOperation execution. 142 | 143 | ### Pattern checks 144 | 145 | With the help of the opcodes and function selectors, contracts can implement security mechanisms which reason about the call patterns in a transaction. We believe that this is one step further in implementing transparent on-chain anomaly-based threat prevention solutions. 146 | 147 | ### Address checks 148 | 149 | While this proposal enhances visibility into addresses involved in a transaction, it does not prescribe how such addresses should be checked. Combining this call stack precompile with complimentary checks for contract reputation and age checks will further enhance transaction screening, but those checks are also outside the scope of this proposal. 150 | 151 | ### Impact on composability 152 | 153 | By itself, the precompile does not impact composability. However, if implemented and leveraged in conjunction with a transaction screening solution, composability may be impacted. Nevertheless, this is viewed as an acceptable result as the authors believe each protocol has the right to manage its own risk and decide for itself what transactions it allows/disallows. 154 | 155 | ## Backwards Compatibility 156 | 157 | The call stack does not affect any previous execution and requires no consensus changes. The precompiled contract, however, can affect how contracts react during transaction execution and should require all clients to upgrade. 158 | 159 | ## Reference Implementation 160 | 161 | https://github.com/ethereum/go-ethereum/pull/28947 162 | 163 | ## Copyright 164 | 165 | Copyright and related rights waived via [CC0](../LICENSE.md). 166 | -------------------------------------------------------------------------------- /RIPS/rip-7696.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7696 3 | title: Precompile for generic DSM (double scalar multiplication) 4 | description: Proposal to add precompiled contract that performs two point multiplication and an addition over any elliptic curve. 5 | author: Renaud Dubois (@rdubois-crypto) 6 | discussions-to: https://ethereum-magicians.org/t/rip7696-generic-double-scalar-multiplication-dsm-for-all-curves/19798 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2024-03-22 11 | --- 12 | 13 | ## Abstract 14 | 15 | This proposal creates two precompiled contracts that perform two point multiplication and sum then over any elliptic curve given `p`, `a`,`b` curve parameters, `Px1`,`Py1` and`Qx2`,`Qy2` coordinates of points P and Q, `u`,`v` two scalars. Thus it computes the value uP+vQ over any given weierstrass curve. One of the precompiles provide extra data (512 bits) to enable a consequent speed-up to any curve. This extra data consists in the points $P_{128}=2^{128}P$ and $Q_{128}=2^{128}Q$. 16 | 17 | ## Motivation 18 | 19 | Account abstraction (EIP 4337, EIP7560) enables to replace EoA with non native signature algorithms. While RIP7212 focuses only on P256, there are many other elliptic curves of interest, subject to change according to latest advances either in ZK proving systems, hardware integration or cross chains requirements. This precompiles can achieve many goals such as Stealth, WebAuthn, Schnorr signatures and cheap bridges with other L2s. While most authentication scheme relies today on ECDSA, Schnorr versions are more MPC and ZK-friendly (faster and more secure). Today one can tweak `ecrecover()` opcode to perform scalar multiplication, given an additional hash. Adding a generic multiplication, in conjugaison with Account Abstraction open the gate for many cheap and powerful use cases. This is a non-exhaustive list of use cases: 20 | 21 | 1. **ed25519 :** Apple secure enclave, Webauthn, OpenSSL, Farcaster, bridges with Cosmos, Solana ecosystems. 22 | 23 | 2. **secp256r1 :** Most of previous use cases plus Android Keystore, Passkeys. 24 | 25 | 3. **bn254-G1 :** Zcash, Tornado Cash, as specified by EIP1962. 26 | 27 | 4. **Jujub :** Circom proving system compatibility. 28 | 29 | 5. **Stark curve :** Starknet Ecosystem. 30 | 31 | 6. **Other curves :** Pasta, Vela, sec256q1 for inner argument constructions. 32 | 33 | This proposal aims to reach maximum security and cryptographic agility for the key management. 34 | While a generic MSM (as proposed by EIP2537, but not limited to BLS12381) would be superior, the variable length and complexity of possible tradeoffs seems to reduce the probability of acceptance. MSM is mainly targeting ZK uses, while for classical non-pairing based cryptography, DSM is the core required operation. 35 | 36 | ## Specification 37 | 38 | ### Constants 39 | 40 | | Name | Value | 41 | |-----------------------|--------| 42 | | FORK_BLOCK | TBD | 43 | | PRECOMPILED_ADDRESS | TBD | 44 | | ECMULMULADD_COST | 3500 | 45 | | ECMULMULADD_B4_COST | 2000 | 46 | 47 | ### New Precompile 48 | 49 | #### Elliptic Curve Information 50 | 51 | Any elliptic curve can be expressed under a Weierstrass form defined by the equation $y^2 ≡ x^3 + ax + b \mod p.$ The minimal information of domain parameters required for ecmulmuladd is defined with the following equation and domain parameters: 52 | 53 | | Name | Value | 54 | |--------|-------------------------------------------------------| 55 | | p | modulus of the elliptic prime field | 56 | | a | elliptic curve short weierstrass first coefficient | 57 | | b | elliptic curve short weierstrass second coefficient | 58 | 59 | ### Required Checks in Verification 60 | 61 | The following requirements **MUST** be checked by the precompiled contract to verify signature components are valid: 62 | 63 | - P and Q coordinates verify the curve equation, 64 | - P and Q coordinates are within prime field range (i.e belong to [0..p-1]). 65 | 66 | The following elements are NOT checked by the precompile: 67 | 68 | - the provided curve is safe regarding classic criteria (twist security, embedded degree, rho security, etc.) 69 | - the provided points belongs to the right subgroup (for non prime order curves) 70 | 71 | As such it is heavily recommended to avoid custom curves without an extended knowledge and examination of the previous criterias. 72 | 73 | ### Precompiled Contracts Specification 74 | 75 | #### ecMulmuladd 76 | 77 | The `ecMulmuladd` precompiled contract is proposed with the following input and outputs, which are big-endian values: 78 | 79 | - **Input data:** 224 bytes of data including: 80 | - 32 bytes of the modulus `p` modulus of the prime field of the curve 81 | - 32 bytes of the `a` first coefficient of the curve 82 | - 32 bytes of the `b` second coefficient of the curve 83 | - 32 bytes of the `Px` x coordinate of the first point 84 | - 32 bytes of the `Py` y coordinate of the first point 85 | - 32 bytes of the `Qx` x coordinate of the first point 86 | - 32 bytes of the `Qy` y coordinate of the first point 87 | - 32 bytes of the `u` first scalar to multiply with P 88 | - 32 bytes of the `v` second scalar to multiply with Q 89 | 90 | - **Output data:** 64 bytes of result data and error 91 | - If the ecmulmuladd process succeeds, it returns the resulting point as 64 bytes of data. The infinity point (neutral for addition law) is represented as the (0,0) couple. 92 | - In case of failure it returns an empty chain 93 | 94 | #### ecMulmuladdB4 95 | 96 | The `ecMulmuladd_b4` precompiled contract is proposed with the following input and outputs, which are big-endian values: 97 | 98 | - **Input data:** 416 bytes of data including: 99 | - 32 bytes of the modulus $p$ 100 | - 32 bytes of the `a` component of the signature 101 | - 32 bytes of the `b` component of the signature 102 | - 32 bytes of the `Px` x coordinate of the first point P 103 | - 32 bytes of the `Py` y coordinate of the first point Q 104 | - 32 bytes of the `P128x` x coordinate of the point $P_{128}=2^{128}P$ 105 | - 32 bytes of the `P128y` y coordinate of the point $P_{128}=2^{128}P$ 106 | - 32 bytes of the `Qx` x coordinate of the second point Q 107 | - 32 bytes of the `Qy` y coordinate of the second point Q 108 | - 32 bytes of the `Q128x` x coordinate of the point $Q_{128}=2^{128}Q$ 109 | - 32 bytes of the `Q128y` y coordinate of the point $Q_{128}=2^{128}Q$ 110 | - 32 bytes of the `u` first scalar to multiply with P 111 | - 32 bytes of the `v` second scalar to multiply with Q 112 | 113 | - **Output data:** 64 bytes of result data and error 114 | - If the ecmulmuladd process succeeds, it returns the resulting point as 64 bytes of data. The infinity point (neutral for addition law) is represented as the (0,0) couple. 115 | - In case of failure it returns an empty chain 116 | 117 | ### Implementation 118 | 119 | The node is free to implement the elliptic computations as it see fit (choice of inner elliptic point reprensentation, ladder, etc). For perfomances reasons, it is recommended to use Montgomery multiplication in combination with the so called Strauss-Shamir's trick (with a 4 dimensional version for ecmulmuladd_b4). Use of windowing and NAF can speed-up implementation further. The use of a 4 dimensional version provides a speed up equivalent to GLV (Gallant-Lambert-Vanstone) optimization. The difference being that additional off chain precomputations are required. 120 | 121 | ### Precompiled Contract Gas Usage 122 | 123 | - The cost of `ecMulmuladd` is `4000` gas. It is related to the increased cost of the extra call data to a specialized implementation, taking the best pure solidity implementation available for generic curves, which is 10% according to our measures. 124 | 125 | - The cost of `ecMulmuladdB4` is `2500` gas. It is the ratio between ecMulmuladd implementation gas cost with and without the extra call data. 126 | 127 | ## Backwards Compatibility 128 | 129 | No backward compatibility issues found as the precompiled contract will be added to `PRECOMPILED_ADDRESS` at the next available address in the precompiled address set. 130 | 131 | ## Test Cases 132 | 133 | ## Reference Implementation 134 | 135 | The Implementation of the `ecMulmuladdB4` precompiled contract is provided as a progressive precompile. Current costs is 160K. 136 | 137 | ## Security Considerations 138 | 139 | The changes are not directly affecting the protocol security. The security is related to the level of investigation the target curve has been through. 140 | 141 | ## Copyright 142 | 143 | Copyright and related rights waived via [CC0](../LICENSE.md). 144 | -------------------------------------------------------------------------------- /RIPS/rip-7711.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7711 3 | title: Validation-Execution Separation in Native Account Abstraction 4 | description: A change in the order of execution of frames of RIP-7560 transactions inside a block that enables efficient block building 5 | author: Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn) 6 | discussions-to: https://ethereum-magicians.org/t/rip-7711-an-rip-7560-compatible-transactions-bundle-transaction-type/20093 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2023-09-01 11 | requires: 7560 12 | --- 13 | 14 | 15 | ## Abstract 16 | 17 | This proposal provides block builders with a mechanism to isolate validation from execution for 18 | a set of RIP-7560 transactions. 19 | By doing so we simplify the task of filling a block gas space with RIP-7560 transactions and prevent potential 20 | denial-of-service attacks against block builders. 21 | 22 | On "single sequencer" Layer 2 chains that do not have a "transaction mempool" in a traditional sense, 23 | this proposal provides no benefit compared to the original RIP-7560. 24 | It is required for DoS mitigation on every chain that does rely on a public mempool for block building, however. 25 | 26 | ## Motivation 27 | 28 | The `AA_TX_TYPE` transaction type that is defined in RIP-7560 completely separates transaction validity 29 | on a protocol level from ECDSA signatures or any other protocol-defined rules, instead allowing account's EVM code 30 | to determine a validity of a transaction. 31 | 32 | This validation EVM code, however, may be affected by any observable state change within a block. 33 | A block builder trying to include a set of `AA_TX_TYPE` transactions may face a challenge of finding a combination 34 | that fits together without invalidating each other. 35 | 36 | The block builder has to execute the entire body of one transaction before picking the next one. 37 | Additionally, it is not feasible to apply any limitations on the transaction execution, while it is expected that 38 | the validation code will be constrained by the block builder with a ruleset like ERC-7562. 39 | 40 | This document proposes a mechanism for block builder to specify a set of `AA_TX_TYPE` transactions that are guaranteed 41 | to fit together due to a fact that all of their validation frames are executed consecutively first, 42 | before their respective execution frames. 43 | 44 | ## Specification 45 | 46 | ### Non-atomic validation and execution transaction type 47 | 48 | ``` 49 | BUNDLE_TRANSACTION_TYPE = x 50 | ``` 51 | 52 | These transactions are completely identical to regular RIP-7560 transactions with the exceptions of being 53 | composed into "AA transaction bundles". 54 | 55 | It is important for the wallets to explicitly opt into this feature by accepting the `BUNDLE_TRANSACTION_TYPE`, 56 | as some Smart Contract Accounts 57 | may be created in a way that relies on atomicity between validation and execution phases. 58 | 59 | ### AA transaction bundles 60 | 61 | In AA transaction bundles, all validation state changes apply before all execution ones. 62 | 63 | Filling a block with AA transactions must not be a challenge for the block builder. 64 | However, if each transaction during its execution can alter any state that affects the validity of another transaction 65 | in the mempool, the block builder will be forced to revalidate all transactions in the mempool after each inclusion. 66 | Transactions of `BUNDLE_TRANSACTION_TYPE` type mitigate the inherent computational complexity of building a block that 67 | contains `AA_TX_TYPE` transactions. 68 | 69 | With `BUNDLE_TRANSACTION_TYPE` transactions, **all** the validation frames 70 | of an uninterrupted sequence of AA transactions are run first, 71 | and **all** the execution frames are run immediately after that. 72 | 73 | ### Validation code sandboxing 74 | 75 | Even with RIP-7711, validation frames of a `BUNDLE_TRANSACTION_TYPE` transactions bundle can invalidate 76 | other transactions in the same bundle. 77 | We define a mechanism to prevent cross-validation dependencies by applying 78 | certain rules for the mempool transactions which is fully described in [ERC-7562](../eip-7562). 79 | This is equivalent to the mechanism used by the ERC-4337 UserOperations mempool. 80 | 81 | A builder that chooses not to enforce the rules from ERC-7562 **must** take care to re-validate each transaction 82 | against the mid-block state at the position where it is being included into a block. 83 | Otherwise, the resulting block is likely to end up being invalid. 84 | 85 | ### Block structure diagram 86 | 87 | Here is a visual representation of a block that contains multiple Account Abstraction Transactions. 88 | The validation parts of AA transactions are executed as separate transactions, 89 | but are not represented as separate transactions in the block data. 90 | 91 | ![](../assets/rip-7711/rip_7711_block_overview.png) 92 | *The structure of a block containing multiple RIP-7711 Native Account Abstraction Transactions* 93 | 94 | For comparison, this is the diagram of a similar block using RIP-7560 transactions: 95 | 96 | ![](../assets/rip-7711/rip_7560_block_overview.png) 97 | *The structure of a block containing multiple RIP-7560 Transactions* 98 | 99 | ### Transaction execution context 100 | 101 | Note that before RIP-7711 some behaviours in the EVM were defined as dependent on the transaction context. 102 | These behaviours are: 103 | 1. Costs of the `SSTORE` opcode per [EIP-2200](../eip-2200) 104 | 2. Costs of accessing cold addresses and slots per [EIP-2929](../eip-2929) 105 | 3. Values available within the transient storage per [EIP-1163](../eip-1163) 106 | 107 | All validation and execution frames of RIP-7711 transactions behave as individual transactions 108 | for the purposes of these EIPs. 109 | 110 | Meaning, for example, that a value set with TSTORE in one frame will not remain available in the next one, 111 | and different transactions will have independent values held in TSTORE slots. 112 | 113 | Notice that the maximum amount of gas refund assigned after the execution per [EIP-3529](../eip-3529) 114 | is applied to the entire RIP-7711 transaction gas cost and is not split into phases. 115 | 116 | ### Behaviour of the `SELFDESTRUCT` opcode 117 | The only exception to the rule defined in the [Transaction execution context](#transaction-execution-context) 118 | section is the availability of the `SELFDESTRUCT` opcode as defined by [EIP-6780](../eip-6780). 119 | Using `SELFDESTRUCT` is only allowed within the same **frame** the contract was created in. 120 | 121 | ### Unused gas penalty charge 122 | 123 | ``` 124 | UNUSED_GAS_PENALTY = 10 125 | ``` 126 | 127 | A penalty of `UNUSED_GAS_PENALTY` percent of the unused `callGasLimit` and `paymasterPostOpGasLimit` is charged from the 128 | transaction `sender` or `paymaster`. 129 | 130 | This penalty is applied to the execution frame and the `postPaymasterTransaction` separately. 131 | The unused gas is calculated as following for the corresponding frames: 132 | 133 | ``` 134 | uint256 unusedGasExecution = executionGasLimit - gasUsedByExecution; 135 | uint256 unusedExecutionGasPenalty = unusedGasExecution * UNUSED_GAS_PENALTY / 10; 136 | ``` 137 | 138 | Note that the `unusedExecutionGasPenalty` is added to the `actualGasUsed` right after the 139 | execution frame completes and before it is passed to the the `postPaymasterTransaction` frame. 140 | 141 | ``` 142 | uint256 unusedGasPostOp = paymasterPostOpGasLimit - gasUsedByPostOp; 143 | uint256 unusedPostOpGasPenalty = unusedGasPostOp * UNUSED_GAS_PENALTY / 10; 144 | ``` 145 | 146 | The `unusedPostOpGasPenalty` is added to the `actualGasUsed` after the `postPaymasterTransaction`. 147 | 148 | ## Rationale 149 | 150 | ### Unused gas penalty charge 151 | 152 | Transactions of type `BUNDLE_TRANSACTION_TYPE` that reserve a lot of gas for themselves using `validationGasLimit`, 153 | `paymasterGasLimit` and `callGasLimit` fields but do not use the reserved gas present a challenge for 154 | block builders. This is especially demanding in case a gas used by a transaction can be significantly different 155 | based on its position within a block, as such transactions may cause the block builder to iterate its algorithm 156 | many times until a fully utilized block is discovered. 157 | 158 | The effects of allowing transactions to specify unrestricted gas limits is shown on this diagram: 159 | ![](../assets/rip-7560/unused_gas_attack_overview.png) 160 | 161 | ### Breaking up a transaction flow into non-atomic pieces 162 | 163 | While changing the transaction flow is a departure from the norm for Ethereum transactions, 164 | in practice this change is both very useful and not very complex. 165 | 166 | The validation frames can be easily constrained with both gas limits and opcode bans. 167 | The entire validation section of a correctly built bundle can therefore be protected from containing 168 | mutually exclusive transactions. 169 | The task of building a block becomes efficient and can be parallelized with no risk of DoS attacks. 170 | 171 | For the EVM implementation the validation frames behave almost identical to a standalone transaction, 172 | so there are no expected difficulties with implementing this proposal. 173 | 174 | ## Backwards Compatibility 175 | 176 | The non-atomic flow of an RIP-7711 transaction requires attention from the Smart Contract Account developers 177 | to ensure the accounts cannot be left in a broken state between the validation and execution frames. 178 | 179 | However, as ERC-4337 has a very similar execution flow for UserOperations, it is a known property of 180 | Account Abstractions and all existing code is likely to be compatible with RIP-7711 with only some minor modifications. 181 | 182 | ## Security Considerations 183 | 184 | ### Attacks on validation-execution separation 185 | 186 | Accounts in RIP-7560 are instructed not to expect the validation and execution to be atomic. 187 | However, wallets may be implemented with an incorrect assumption that nothing can happen 188 | between validation and execution phases, which is wrong. 189 | 190 | The state that exists at the end of the validation frame may be observed or modified by unrelated contracts before 191 | the execution frame begins. 192 | Smart Contract Account developers contracts must ensure that their code does not make any false assumptions. 193 | 194 | ## Copyright 195 | 196 | Copyright and related rights waived via [CC0](../LICENSE.md). 197 | -------------------------------------------------------------------------------- /RIPS/rip-7712.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7712 3 | title: Enable RIP-7560 transactions using a two-dimensional nonce 4 | description: An RIP-7560 transaction modification that allows Smart Contract Accounts to define their own transaction sequencing 5 | author: Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn) 6 | discussions-to: https://ethereum-magicians.org/t/rip-7712-multi-dimensional-256-bit-nonce-for-rip-7560-account-abstraction-transactions/20094 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2023-09-01 11 | requires: 7560 12 | --- 13 | 14 | ## Abstract 15 | 16 | An RIP-7560 transaction modification that replaces the existing nonce-based sequencing mechanism 17 | of Ethereum with an on-chain pre-deployed contract in order to provide Smart Contract Accounts 18 | with the flexibility they need to support some advanced use cases. 19 | 20 | ## Motivation 21 | 22 | The traditional nonce-based system provides guarantees of transaction ordering and replay protection, 23 | but does so at the expanse of configurability. 24 | Accounts are not able to express their intentions like "allow these three transactions to be mined in 25 | whatever order" or "these two sets of transactions must have separate sequential nonces". 26 | 27 | However, with Smart Contract Accounts this creates a bottleneck for some use-cases. 28 | For example, Smart Contract Accounts designed to be operated by multiple participants simultaneously, 29 | will require these participants to coordinate their transactions to avoid invalidating each other. 30 | 31 | Another example when this can also be a limitation is a case where there are separate execution flows. 32 | A configuration change may require multiple participants to co-sign a transaction but a regular operation does not. 33 | With sequential nonces, all operations will have to be halted until the configuration change is executed. 34 | 35 | Having a more agile ordering and replay protection system will significantly improve the user experience with RIP-7560. 36 | 37 | Additionally, this change is required for the Native Account Abstraction to achieve feature parity and compatibility 38 | with ERC-4337, as all ERC-4337 Smart Contract Accounts already use the solution described below. 39 | 40 | ## Specification 41 | 42 | ### Constants 43 | 44 | | Name | Value | 45 | |--------------------------|-------| 46 | | AA_BASE_GAS_COST | 15000 | 47 | | AA_BASE_GAS_COST_RIP7712 | 10000 | 48 | | AA_NONCE_MANAGER | tbd | 49 | 50 | ### Non-sequential nonce support 51 | 52 | 53 | We propose an introduction of the `nonceKey` parameter to provide a second dimension 54 | for the RIP-7560 transaction's `nonce` parameter. 55 | 56 | The two-dimensional nonce value of the transaction is represented as `uint256 nonceKey || uint256 nonceSequence` value. 57 | The contract account nonce is then defined as a mapping `address account => uint256 nonceKey => uint256 nonceSequence`. 58 | This approach guarantees unique transaction nonce and hash but removes the requirement of nonces being sequential 59 | numbers. 60 | 61 | This two-dimensional nonce mechanism is exposed to the EVM in a `NonceManager` pre-deployed contract 62 | located at the `AA_NONCE_MANAGER` address. 63 | 64 | The two-dimensional nonce is [validated and incremented](#nonce-validation-frame) on-chain 65 | as part of a `AA_TX_TYPE` transaction validation before the rest of the validation code. 66 | 67 | ### Nonce validation 68 | 69 | We propose to introduce a new validation frame to the RIP-7560 transaction validation flow. 70 | This validation frame performs an on-chain nonce validation and runs before all other frames in a transaction. 71 | 72 | If nonceKey is zero (non-existent), the nonce field is compared to the system nonce, 73 | and then the system nonce is incremented. 74 | The transaction's base cost is `A_BASE_GAS_COST`. 75 | 76 | If `nonceKey` is non-zero, then the `NonceManager` is called to [validate and increment](#nonce-validation-frame) 77 | the nonce for this key, and the base cost is `AA_BASE_GAS_COST_RIP7712`, as the `NonceManager` frame is paid separately. 78 | In this case, the old system `nonce` is not checked and not incremented. 79 | 80 | ### Deployment transaction 81 | 82 | During the account deployment transaction, the `nonceKey` MUST be zero. 83 | The old system `nonce` parameter is not incremented before the transaction: 84 | the `CREATE` or `CREATE2` opcode used by the deployer 85 | will cause the nonce to be incremented to 1 according to [EIP-161](https://eips.ethereum.org/EIPS/eip-161). 86 | 87 | ### The legacy `nonce` account parameter use 88 | 89 | The legacy 64-bit `nonce` account parameter is used when the `nonceKey` parameter of the `AA_TX_TYPE` transaction 90 | is set to 0. 91 | 92 | The legacy `nonce` account parameter is also use for transactions initiated by EOAs, for the `CREATE` opcode and for EIP-7702 authorizations. 93 | 94 | ### Account deployment transaction does not increment the legacy `nonce` 95 | 96 | The first `AA_TX_TYPE` transaction that contains a `deployer` and `deployerData` fields to create the `sender` account 97 | does not increment the `sender`'s legacy `nonce` account parameter even in case the `key` parameter is set to 0. 98 | 99 | #### Nonce validation frame 100 | 101 | Before the first RIP-7560 transaction type defined validation frame is applied during the validation phase, 102 | the `NonceManager` is invoked with the following data: 103 | 104 | ``` 105 | sender{20 bytes} nonceKey{32 bytes} nonceSequence{32 bytes} 106 | ``` 107 | 108 | The gas costs of this validation frame are counted towards the total for a transaction, 109 | and is deducted from the account's `validationGasLimit`. 110 | 111 | #### Nonce query frame 112 | 113 | In order to query its current `nonceSequence` for a given `nonceKey`, the user performs a view call 114 | to the `NonceManager` contract with the following data: 115 | 116 | ``` 117 | sender{20 bytes} nonceKey{32 bytes} 118 | ``` 119 | 120 | The returned value of this call is the current `nonceSequence` that can be used 121 | in the [nonce validation frame](#nonce-validation-frame). 122 | 123 | #### NonceManager Pseudocode 124 | 125 | ``` 126 | if evm.caller == AA_ENTRY_POINT: 127 | validate_increment() 128 | else: 129 | get() 130 | def get(): 131 | if len(evm.calldata) != 52: 132 | evm.revert() 133 | // address sender, 256 bit nonce key 134 | address = to_uint160_be(evm.calldata[0:20]) 135 | key = to_uint256_be(evm.calldata[20:52]) 136 | nonce = storage.get(keccak(address, key)) 137 | evm.return(nonce) 138 | def validate_increment(): 139 | address = to_uint256_be(evm.calldata[0:20]) 140 | key = to_uint256_be(evm.calldata[20:52]) 141 | nonce = to_uint256_be(evm.calldata[52:84]) 142 | current_nonce = storage.get(keccak(address, key)) 143 | if (nonce != current_nonce): 144 | evm.revert() 145 | storage.set(keccak(address, key), current_nonce + 1) 146 | ``` 147 | 148 | #### NonceManager Bytecode and deployment 149 | 150 | TODO. 151 | 152 | ## Rationale 153 | 154 | ### Creating a pre-deployed contract instead of modifying an account data structure 155 | 156 | While there is no technical benefit to either option, allowing EVM code to control the nonce 157 | seems to be a smaller change to the Ethereum protocol and is more aligned with the vision of Account Abstraction. 158 | 159 | ### Account deployment transaction does not increment the legacy `nonce` 160 | 161 | The [EIP-684](https://eips.ethereum.org/EIPS/eip-684) explicitly prevents deployment of contracts for accounts with 162 | non-zero nonce value. This rule collides with the normal flow of incrementing the `sender` nonce before execution 163 | of a transaction starts. 164 | However, [EIP-161](https://eips.ethereum.org/EIPS/eip-161) guarantees that the `nonce` of a newly created account 165 | is set to `1` on creation. 166 | 167 | This guarantees that the `sender` deployment transaction can pass the EIP-684 rule check and still increment the nonce. 168 | 169 | Note that revert in the creation frame makes the `AA_TX_TYPE` transaction invalid and `sender`'s nonce 170 | cannot be incremented without successfully deploying its code. 171 | 172 | ## Backwards Compatibility 173 | 174 | As actual `nonce` value was never observable inside the EVM, there should be no major complications caused by the 175 | migration to a different nonce mechanism. 176 | 177 | 178 | Applications should not assume that `eth_getTransactionCount` method returns the total transactions for an account 179 | 180 | ### EIP-7702 authorization revocation with a nonce bump 181 | 182 | In EIP-7702 the EOA is able to revoke an "authorization tuple" it has previously signed as long as it has not been 183 | included on-chain. 184 | This can be done by incrementing the EOAs `nonce`, which in turn can only be done by sending a new transaction. 185 | With RIP-7712, however, there exists a new way of sending a transaction without affecting the legacy `nonce` field. 186 | Such a transaction will not invalidate the previously signed "authorization tuple" either. 187 | Users who are unaware of this change may not expect an "authorization tuple" to remain valid after sending a different 188 | transaction and should be aware of the existence of RIP-7712 and multidimensional nonces. 189 | 190 | ## Security Considerations 191 | 192 | Smart Contract Accounts that need to enforce the sequence of transaction execution must apply appropriate restrictions 193 | on the `nonceKey` value. 194 | 195 | In order to require the incremental sequential `nonce` behaviour on-chain, the contracts 196 | may choose to `require(nonceKey == 0)`. 197 | 198 | ## Copyright 199 | 200 | Copyright and related rights waived via [CC0](../LICENSE.md). 201 | -------------------------------------------------------------------------------- /RIPS/rip-7728.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7728 3 | title: Precompile for L1SLOAD 4 | description: Proposal to add precompiled contract that load L1 storage slots. 5 | author: Haichen Shen (@icemelon), Péter Garamvölgyi (@Thegaram) 6 | discussions-to: https://ethereum-magicians.org/t/rip-7728-l1sload-precompile/20388 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2024-06-24 11 | --- 12 | 13 | ## Abstract 14 | 15 | This proposal introduces a new precompiled contract `L1SLOAD` that loads several storage slots from L1 given a contract address and storage keys. 16 | 17 | ## Motivation 18 | 19 | With the plethora of L2s on the Ethereum, building multi-chain smart contracts has become challenging. This proposal provides a convenient and trustless way for smart contracts deployed on an L2 chain to read storage values from L1. This improves the developer experience by removing the need for developers to generate and submit MPT proofs themselves. 20 | 21 | An example use case is key management for smart accounts (multisigs and AA wallets). When a wallet already exists on L1, users no longer need to set up the configuration and signing keys on L2 but they can instead load them directly from L1. We believe there are many other use cases that could benefit from direct access to L1 state. 22 | 23 | There have been similar proposals before from the community. Brecht Devos proposed [`L1CALL`](https://ethresear.ch/t/cross-layer-communication-trivially-provable-and-efficient-read-access-to-the-parent-chain/15396) that allows contracts on L2 to call contracts deployed on L1. Optimism had a similar RFP for [remote static call](https://github.com/ethereum-optimism/ecosystem-contributions/issues/76). While the proposed static call mechanism is more powerful than simple state reads, it forces L1 EVM execution to be part of L2s which hinders its adoption by L2 chains. The `L1SLOAD` provides more fundamental functionality and allows more flexibility to L2s because (a) it is easier for L2s to modify the EVM and (2) this precompile might be implemented even by totally non-EVM compatible L2s. 24 | 25 | 26 | ## Specification 27 | 28 | ### Constants 29 | 30 | | Name | Value | 31 | |:---------------------:|:----------------:| 32 | | PRECOMPILED_ADDRESS | TBD | 33 | | FIXED_GAS_COST | 2000 (tentative) | 34 | | PER_LOAD_GAS_COST | 2000 | 35 | | MAX_NUM_STORAGE_SLOTS | 5 (tentative) | 36 | 37 | ### Precompile 38 | 39 | The inputs to the `L1SLOAD` precompile are an L1 contract address and $k$ storage keys up to `MAX_NUM_STORAGE_SLOTS`. 40 | 41 | | Byte range | Name | Description | 42 | | --- | --- | --- | 43 | | [0: 19] (20 bytes) | `address` | The contract address | 44 | | [20: 51] (32 bytes) | `key1` | The storage key | 45 | | ... | ... | ... | 46 | | [`k`\*32-12: `k`\*32+19] (32 bytes) | `keyk` | The storage key | 47 | 48 | The output is the L1 storage value at the latest L1 block number known to the L2 sequencer. 49 | 50 | | Byte range | Name | Description | 51 | | --- | --- | --- | 52 | | [0: 31] (32 bytes) | `value1` | The L1 storage value | 53 | | ... | ... | ... | 54 | | [(`k`-1)\*32: `k`\*32] (32 bytes) | `valuek` | The L1 storage value | 55 | 56 | ### Implementation 57 | 58 | **Prerequisite 1**: The L2 sequencer has access to an L1 node. Given that the sequencer needs to monitor deposit transactions from L1, it already embeds an L1 node inside (preferred) or has access to an L1 PRC endpoint. 59 | 60 | The introduction of the `L1SLOAD` precompile may increase the requirement for the L1 node or the L1 RPC endpoint to be an archive node when the L2 node syncs the L2 chains from older blocks. 61 | 62 | **Prerequisite 2**: The L2 sequencer has a notion of the *latest seen L1 block*, which is deterministic over all L2 nodes, i.e. it is part of the L2 state machine. The exact mechanism is not in scope for this RIP. 63 | 64 | **Implementation**: When the L2 node encounters a call to the `L1SLOAD` precompiled contract, it first verifies that its input is well-formed. It then retrieves its latest seen L1 block number `l1BlockNumber` and sends an RPC query `eth_getStorageAt(address, storageKey, l1BlockNumber)` to the L1 node. Finally, it writes the received storage value to the designated output buffer. 65 | 66 | ### Errors 67 | 68 | There are a few error cases that the `L1SLOAD` precompile needs to handle 69 | - **Invalid input**: when the input is invalid, the gas provided is consumed and there is no return data. This can be due to an incorrect number of bytes provided to the precompile. 70 | - **Invalid output buffer**: when the output buffer is not large enough to hold the return data. 71 | - **Insufficient gas**: when not enough gas was provided, there is no return data. 72 | - **RPC error**: when the L2 sequencer receives the RPC error from the L1 node, the L2 sequencer should retry the RPC request or reinsert the transaction into the txpool. This case should not lead to revert, because that could lead to inconsistency when other nodes replay the transaction. Therefore, this should be treated as an internal error instead of an execution error. 73 | 74 | ### Gas Cost 75 | 76 | The gas costs for `L1SLOAD` is `FIXED_GAS_COST + k * PER_LOAD_GAS_COST`, where `k` is the number of storage slots. The constants are subject to change after more benchmarks. 77 | 78 | The `FIXED_GAS_COST` accounts for the additional RPC call latency to the L1 client. All storage keys are treated as cold keys in the `L1SLOAD` and thus uses 2000 gas for each storage slots to be loaded. 79 | 80 | ### Example 81 | 82 | Here is an example Solidity code snippet to use the `L1SLOAD` precompile. 83 | 84 | ```solidity= 85 | function loadFromL1(address l1Address, uint256 key1, uint256 key2) public view returns (uint256, uint256) { 86 | address L1_SLOAD_ADDRESS = 0x101; 87 | (bool success, bytes memory ret) = L1_SLOAD_ADDRESS.staticcall( 88 | abi.encodePacked(l1Address, key1, key2) 89 | ); 90 | if (!success) { 91 | revert("L1SLOAD failed"); 92 | } 93 | return abi.decode(ret, (uint256, uint256)); 94 | } 95 | ``` 96 | 97 | ## Rationale 98 | 99 | ### Which L1 block does `L1SLOAD` read the storage value at? 100 | 101 | According to the specification defined above, `L1SLOAD` returns the storage value at the latest L1 block known to the L2 sequencer. There are two related issues: 102 | - How to guarantee the consistent return value of `L1SLOAD` 103 | - The risk of loading the storage value from a very stale L1 state. 104 | 105 | First, to ensure the return value is consistent during transaction replay, L2 chains should provide a system contract that stores the information of the latest L1 block known to L2 sequencer. Optimism already provides a predeployed contract [`L1Block`](https://docs.optimism.io/stack/protocol/rollup/smart-contracts#l1block). Scroll has a new system contract [design](https://www.notion.so/scrollzkp/L1Blocks-System-Contract-b1a137eacea74819a3fa57d7d6e52498?pvs=4) that trustlessly imports the L1 block information and also stores other header fields such as state root, timestamp, RANDAO, etc. 106 | 107 | Second, L2 protocols determine the L1 block import delay at their own discretion. To make `L1SLOAD` more useful and reduce the risk of reading stale L1 storage states, we argue that the import delay should not be too long, e.g., waiting for finalized state that usually takes about 18-19 minutes. We suggest to wait for around 10 L1 block confirmations that has low risk of Ethereum chain re-organization while the import delay is fairly short (around 2 min). To adopt this, the L2 sequencers need to be capable of handling the situation when there is a long L1 chain re-organization. Furthermore, if the application is sensitive to stale storage reads, developers can limit the difference between the L1 block number retrieved from the system contract and the latest L1 block number per application requirement. 108 | 109 | ### The overhead to L2 sequencers from additional RPC latency 110 | The `L1SLOAD` precompile introduces risks of additional RPC latency and intermittent RPC errors. Both risks can be mitigated by running a L1 node in the same cluster as the L2 sequencer. It is preferrable for a L2 operator to run their own L1 node instead of using third party to get better security and reliability. We will perform more benchmarks to quantify the latency overhead in such setting. 111 | 112 | ## Proof Mechanism 113 | 114 | Since the `L1SLOAD` precompile directly returns storage values without verifying Merkle inclusion proofs, the responsibility of proving the correctness comes to L2 protocols. Here we briefly describe the method to prove the `L1SLOAD`: 115 | - First, we need to validate the state root of the last known L1 block. We assume the L1 block system contract stores some information of L1 block header, such as blockhash or state root. If the state root is stored in the system contract, the L1 state root can be directly read from the system contract and the validation of the state root is left to the design of the L1 block system contract. If only blockhash is stored in the contract, the state root can be decoded from the blockhash by providing the block header. 116 | - Second, we need to prove the correctness of storage values. Zk rollups can use the storage Merkle inclusion proofs as witness data and validate the Merkle path to the L1 state root in the circuit. Similarly, Optimistic rollups can prove the Merkle inclusion proofs as part of the fraud proof. 117 | 118 | ## Backwards Compatibility 119 | 120 | No backward compatibility issues found as the precompiled contract will be added to `PRECOMPILED_ADDRESS` at the next available address in the precompiled address set. 121 | 122 | -------------------------------------------------------------------------------- /RIPS/rip-7740.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7740 3 | title: Preinstall deterministic deployment factories 4 | description: Proposal to add deployment factory contracts at common addresses to enable deterministic contract deployments 5 | author: Richard Meissner (@rmeissner), Mikhail Mikheev (@mmv08), Nicholas Rodrigues Lordello (@nlordell) 6 | discussions-to: https://ethereum-magicians.org/t/rrc-7740-add-pre-installs-for-deployment-factories/22544 7 | status: Draft 8 | type: Standards Track 9 | category: RRC 10 | created: 2024-06-24 11 | --- 12 | 13 | ## Abstract 14 | 15 | This proposal introduces a set of deployment factory contracts to be preinstalled at common addresses. This will enable deterministic contract deployment to the same address across different networks. 16 | 17 | ## Motivation 18 | 19 | Many projects rely on deployment factories that make use of `create2` to increase the security and determinism of deployments. Utilizing `create2` has a couple of major advantages: 20 | - The address does not depend on the deployment key, therefore reducing the need to manage a deployment key 21 | - The address of the contract is tied to the deployment code, which provides strong guarantees on the deployed code 22 | - Contracts can be redeployed in case of a selfdestruct 23 | 24 | The downside is that it is still necessary to deploy these deployment factories. There are two common ways to do so: 25 | - Utilize a randomly generated signature for fixed deployment transactions 26 | - Manage a deployment key for the deployment factory. 27 | 28 | Using a randomly generated signature for a fixed deployment transaction has the advantage that this is a fully trustless process, and no deployment key has to be managed. But the parameter of the signed deployment transaction cannot be changed, therefore it is not possible to adjust the gas price, gas limits or set the chain ID. 29 | 30 | Providing a stable way for deterministic and trustless deployments will become even more important with EIPs like EIP-7702. The strong guarantees provided by a deployment factory are extremely helpful in this case, as this EIP depends on the code at a specific address. 31 | 32 | This RIP proposes aligning on a set of deterministic deployment factories and preinstalling these on all Rollups to enable developers to rely on such libraries. Some rollups, such as Optimism, already have a set of preinstalled contracts for deterministic deployments, and this proposal aims to extend this set to other Rollup stacks to prevent fragmentation. 33 | 34 | ## Specification 35 | 36 | ### Factories 37 | 38 | The following factories should be added: 39 | - [Deterministic Deployment Proxy](https://github.com/Arachnid/deterministic-deployment-proxy) at `0x4e59b44847b379578588920ca78fbf26c0b4956c` 40 | - [Safe Singleton Factory](https://github.com/safe-global/safe-singleton-factory) at `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7` 41 | - [CreateX](https://github.com/pcaversaccio/createx) at `0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed` 42 | - [Create2 Deployer](https://github.com/pcaversaccio/create2deployer) at `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2` 43 | 44 | For factories with a managed key, the nonce of the deployer account should be kept as is since the factories are not destructible and CREATE opcodes [revert](https://eips.ethereum.org/EIPS/eip-684) in case of a collision. 45 | 46 | ### References 47 | 48 | - [OP Stack Preinstalls](https://docs.optimism.io/builders/chain-operators/features/preinstalls) 49 | 50 | ## Rationale 51 | 52 | ### Why not align on one factory? 53 | 54 | The listed factories are already in active use on multiple networks. To ensure future compatibility without having to redeploy existing contracts, it makes the most sense to enable a set of deployment factories that also cover a large part of the existing ecosystem. 55 | 56 | ## Backwards Compatibility 57 | 58 | One potential issue that is unlikely to arise is a rogue actor obtaining access to a deployer key of one of the key-managed factories and deploying a different bytecode at the factory address to one of the networks affected by the proposal. If this happens before the proposal is implemented, the Authors propose two potential solutions: 59 | - Revisit the list of factories 60 | - Overwrite the code at the address. 61 | 62 | No other backward compatibility issues were found. 63 | -------------------------------------------------------------------------------- /RIPS/rip-7755.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7755 3 | title: Cross-L2-Call 4 | description: Contract standard for cross-L2 calls facilitation 5 | author: Wilson Cusack (@WilsonCusack), Jack Chuma (@jackchuma) 6 | discussions-to: https://ethereum-magicians.org/t/rip-contract-standard-for-cross-l2-calls-facilitation 7 | status: Draft 8 | type: Standards Track 9 | category: RRC 10 | created: 2024-08-11 11 | --- 12 | 13 | ## Abstract 14 | 15 | This proposal introduces a standard for facilitating cross-chain calls within the Ethereum ecosystem. It aims to minimize trust assumptions by means of a proof system that leverages state sharing between Ethereum and its rollups. This proof system verifies destination chain call execution, enabling secure compensation for offchain agents that process requested transactions. 16 | 17 | ## Motivation 18 | 19 | Cross-chain interactions are fundamental to the modern cryptocurrency user experience. Current solutions for Ethereum networks face several key limitations: 20 | 21 | 1. Dependence on centralized, permissioned relayers 22 | 1. Reliance on protocols external to Ethereum and its rollups 23 | 1. Abstracted, intent-based architectures that restrict direct control over execution 24 | 25 | Ethereum L2s, which all record state in a shared execution environment, are well-suited to provide an alternative. Users of EVM chains should have access to a public, decentralized utility for executing cross-chain calls. 26 | 27 | From any EVM chain, users should be able to initiate a call on any other EVM chain while utilizing a compensation mechanism to influence the probability of its execution. 28 | 29 | Users must have complete assurance that compensation is only provided if the call is executed. This assurance should rely solely on onchain information. 30 | 31 | ## Specification 32 | 33 | The system relies on three main components: 34 | 35 | - Message Passing Contracts: A source chain `Outbox` and a destination chain `Inbox` for sending / receiving messages as well as processing fulfiller compensation. 36 | - Relayers: Sophisticated offchain actors (called "fulfillers") that relay messages to destination chains on behalf of users. 37 | - Settlement Layer: A mechanism for validating destination chain call delivery to allow fulfiller compensation on source chain. 38 | 39 | This proposal assumes all Ethereum L2s post state representations to Ethereum mainnet. L2s that expose L1 state within their execution environment gain a unique capability: they can prove the state of any other L2 connected to Ethereum. This fundamental property enables the trustless settlement layer via EIP-1186 storage proofs that are described in detail below. 40 | 41 | ### Request Flow 42 | 43 | ![image](../assets/rip-7755/happy_case.png "Happy case flow") 44 | 45 | 1. User submits request with reward funds to `Outbox` 46 | 1. `Outbox` emits discovery event 47 | 1. Fulfiller relays request to destination chain's `Inbox`, including any required execution funds 48 | 1. `Inbox` executes the requested cross-chain calls 49 | 1. `Inbox` stores execution receipt in contract storage 50 | 1. After a specified delay, fulfiller submits proof to `Outbox` 51 | 1. Upon successful proof validation, reward is released to fulfiller 52 | 53 | > [!NOTE] 54 | > 55 | > - The following specifications use syntax from Solidity `0.8.24` (or above). 56 | 57 | ### Data Structures 58 | 59 | #### Call 60 | 61 | Represents a low-level call specification for a transaction on the destination chain. 62 | 63 | Fields: 64 | 65 | - `to`: Address to be called converted to a bytes32 format 66 | - `data`: Calldata for the call 67 | - `value`: Native asset value for the call 68 | 69 | ```solidity 70 | struct Call { 71 | bytes32 to; 72 | bytes data; 73 | uint256 value; 74 | } 75 | ``` 76 | 77 | ### Outbox 78 | 79 | The Outbox contract, deployed on the origin chain, manages cross-chain call requests and reward distributions. It validates request fulfillment through storage proofs and must implement the following interface. 80 | 81 | #### Events 82 | 83 | ##### MessagePosted 84 | 85 | Emitted when a user initiates a cross-chain call request. 86 | 87 | **Parameters:** 88 | 89 | - `messageId` (bytes32, indexed): Keccak256 hash of the message request 90 | - `sourceChain` (bytes32) The chain identifier of the source chain 91 | - `sender` (bytes32) The account address of the sender 92 | - `destinationChain` (bytes32) The chain identifier of the destination chain 93 | - `receiver` (bytes32) The account address of the receiver 94 | - `payload` (bytes) The encoded message to be executed on the destination chain 95 | - `attributes` (bytes[]) The attributes to be included in the message 96 | 97 | ```solidity 98 | event MessagePosted( 99 | bytes32 indexed messageId, 100 | bytes32 sourceChain, 101 | bytes32 sender, 102 | bytes32 destinationChain, 103 | bytes32 receiver, 104 | bytes payload, 105 | bytes[] attributes 106 | ); 107 | ``` 108 | 109 | ##### CrossChainCallCompleted 110 | 111 | Emitted when a fulfiller successfully claims their reward for executing a cross-chain call. 112 | 113 | **Parameters:** 114 | 115 | - `messageId` (bytes32, indexed): Keccak256 hash of the message request 116 | - `submitter` (address): Address of the fulfiller that claimed 117 | 118 | ```solidity 119 | event CrossChainCallCompleted(bytes32 indexed messageId, address submitter); 120 | ``` 121 | 122 | ##### CrossChainCallCanceled 123 | 124 | Emitted when an expired request is canceled. 125 | 126 | **Parameters:** 127 | 128 | - `messageId` (bytes32, indexed): Keccak256 hash of the message request 129 | 130 | ```solidity 131 | event CrossChainCallCanceled(bytes32 indexed messageId); 132 | ``` 133 | 134 | #### Methods 135 | 136 | ##### sendMessage 137 | 138 | Initiates a cross-chain call request. 139 | 140 | **Requirements:** 141 | 142 | - Must emit `MessagePosted` 143 | - Must lock the reward amount in the contract 144 | - Must specify the receiver as either an `Inbox` contract on the destination chain, or the ERC-4337 `EntryPoint` contract 145 | - The payload is either an encoded `Call` array, or an encoded `UserOp` 146 | - See [Cross-Chain UserOps](#cross-chain-user-operations) for account abstraction considerations 147 | 148 | ```solidity 149 | function sendMessage( 150 | bytes32 destinationChain, 151 | bytes32 receiver, 152 | bytes calldata payload, 153 | bytes[] calldata attributes 154 | ) external payable returns (bytes32); 155 | ``` 156 | 157 | ##### claimReward 158 | 159 | Allows fulfillers to claim rewards by providing proof of successful cross-chain execution. 160 | 161 | **Requirements:** 162 | 163 | - Must verify the proof 164 | - Must emit `CrossChainCallCompleted` event 165 | - Must transfer reward to the specified `payTo` address 166 | 167 | ```solidity 168 | function claimReward( 169 | bytes32 destinationChain, 170 | bytes32 receiver, 171 | bytes calldata payload, 172 | bytes[] calldata attributes, 173 | bytes calldata proof, 174 | address payTo 175 | ) external; 176 | ``` 177 | 178 | ##### cancelRequest 179 | 180 | Cancels an expired request and refunds the reward. 181 | 182 | **Requirements:** 183 | 184 | - Must verify request expiration 185 | - Must emit `CrossChainCallCanceled` 186 | - Must refund reward to original requester 187 | 188 | ```solidity 189 | function cancelMessage( 190 | bytes32 destinationChain, 191 | bytes32 receiver, 192 | bytes calldata payload, 193 | bytes[] calldata attributes 194 | ) external; 195 | ``` 196 | 197 | ### Inbox 198 | 199 | The inbox contract on the destination chain functions as a router for requested calls and maintains a receipt of request fulfillment. 200 | 201 | #### Data Structures 202 | 203 | ##### FulfillmentInfo 204 | 205 | This structure holds details about the fulfillment of a request. 206 | 207 | Fields: 208 | 209 | - `timestamp`: The block timestamp when the request was fulfilled. 210 | - `fulfiller`: The address of the entity that successfully completed the call. 211 | 212 | ```solidity 213 | struct FulfillmentInfo { 214 | uint96 timestamp; 215 | address fulfiller; 216 | } 217 | ``` 218 | 219 | #### Events 220 | 221 | ##### CallFulfilled 222 | 223 | This event is emitted when a cross-chain call request is fulfilled. 224 | 225 | **Parameters**: 226 | 227 | - `messageId`: The keccak256 hash of the message request. 228 | - `fulfilledBy`: The address of the entity that successfully completed the call. 229 | 230 | ```solidity 231 | event CallFulfilled(bytes32 indexed messageId, address indexed fulfilledBy); 232 | ``` 233 | 234 | #### Methods 235 | 236 | ##### fulfill 237 | 238 | This method routes the requested calls to specified destinations and records a receipt of the fulfillment. 239 | 240 | **Requirements:** 241 | 242 | - Must execute requested `Call`'s 243 | - Must emit `CallFulfilled` event 244 | - Once `FulfillmentInfo` is stored, the receipt is immutable 245 | - Must only store `FulfillmentInfo` if all calls are successful 246 | 247 | Note: The caller specifies a custom fulfiller address, allowing a different address to claim rewards. 248 | 249 | ```solidity 250 | function fulfill( 251 | bytes32 sourceChain, 252 | bytes32 sender, 253 | bytes calldata payload, 254 | bytes[] calldata attributes, 255 | address fulfiller 256 | ) external payable; 257 | ``` 258 | 259 | ### Storage Proof Validation 260 | 261 | Storage proof validation is used within the Outbox contract to ensure the execution receipt exists in the destination chain `Inbox` storage before releasing a reward to the fulfiller. Storage proof validation implementations are chain-specific, which is why the `claimReward` function in the `Outbox` contract accepts the `proof` parameter as a generic `bytes` type. While specific proof formats may vary between implementations, all should follow this core validation sequence: 262 | 263 | ![image](../assets/rip-7755/state_root_sharing.png "Storage proof validation") 264 | 265 | > [!NOTE] 266 | > Visual elements in diagram: 267 | > 268 | > - Networks: Gray background 269 | > - Contracts: Purple background 270 | > - Storage values: Yellow background 271 | > 272 | > Chain definitions: 273 | > 274 | > - Chain A: Source chain 275 | > - Chain B: Destination chain 276 | > 277 | > This example shows validation steps for an L2 -> L1 -> L2 route 278 | 279 | Validation Steps: 280 | 281 | 1. Verify that the proof's beacon root corresponds to the root exposed in Chain A's execution environment. 282 | 1. Verify L1 execution client's state root against the beacon root. 283 | 1. Verify Chain B's rollup contract storage root against L1 execution client's state root. 284 | 1. Verify Chain B's state root against its rollup contract storage root. 285 | 1. Verify Chain B's inbox contract storage root against Chain B's state root. 286 | 1. Verify the `FulfillmentInfo` struct at the specified storage key against Chain B's inbox contract storage root. 287 | 288 | **Important Implementation Note:** 289 | Some L2 chains store an "output root" on L1 instead of directly storing their state root. In these cases, an additional validation step is required between steps 4 and 5. This step must: 290 | 291 | 1. Provide the destination chain's state root 292 | 2. Apply chain-specific logic to derive the output root using the state root and any auxiliary data 293 | 3. Verify the derived output root matches the proven value in the destination chain's rollup contract on L1 294 | 295 | ### Message Customization 296 | 297 | The message or request structure allows flexibility to customize the behavior of the message delivery on destination chain as well as the settlement system for verification. This flexibility is achieved through the use of ERC-7786 inspired attributes. Each attribute is a bytes string beginning with a 4 byte selector followed by abi-encoded data. 298 | 299 | #### [REQUIRED] Nonce Attribute 300 | 301 | - Selector: `0xce03fdab` 302 | - Contents: 303 | - Nonce value (`uint256`) 304 | 305 | The nonce attribute prevents message ID clashing by ensuring all requests are unique. The Outbox is expected to validate the existence and correctness of the provided nonce. 306 | 307 | #### [REQUIRED] Delay Attribute 308 | 309 | - Selector: `0x84f550e0` 310 | - Contents: 311 | - Finality delay (`uint256`) 312 | - Expiry (`uint256`) 313 | 314 | The delay attribute is required for setting request expiration. It can also optionally set a finality delay that is used to prevent the fulfiller from claiming their reward too soon. That's necessary if the proof is against unfinalized state for an optimistic rollup. If the proof is against finalized state, the finality delay is unnecessary and can be ignored by the Outbox. The expiration is required in all cases and is used to ensure fulfillers have enough time to claim rewards after request delivery without the possibility of users taking their funds back. 315 | 316 | ##### Request Flow with Finality Delay 317 | 318 | ![image](../assets/rip-7755/request_flow_finality_delay.png "Request flow with finality delay") 319 | 320 | ##### Cancelled Request Flow 321 | 322 | ![image](../assets/rip-7755/cancelled_request.png "Expired request gets cancelled") 323 | 324 | #### [OPTIONAL] Precheck Attribute 325 | 326 | - Selector: `0xbef86027` 327 | - Contents: 328 | - Destination chain Precheck contract address (`bytes32`) 329 | 330 | The precheck mechanism allows the requester to guarantee some destination chain condition is true in order for their request to be delivered. This is done by deploying a precheck contract to the destination chain that validates some arbitrary condition. The precheck contract must implement the following interface and is invoked before request fulfillment. 331 | 332 | ![image](../assets/rip-7755/call_delivery_precheck.png "Call delivery with precheck") 333 | 334 | **Requirements:** 335 | 336 | - Must revert if validation conditions are not met 337 | - Includes the cross chain request and caller address as parameters. Caller is the address of the fulfiller that submitted the transaction to `Inbox`. 338 | 339 | ```solidity 340 | function precheckCall( 341 | bytes32 sourceChain, 342 | bytes32 sender, 343 | bytes calldata payload, 344 | bytes[] calldata attributes, 345 | address caller 346 | ) external view;; 347 | ``` 348 | 349 | #### [OPTIONAL] MagicSpend Attribute 350 | 351 | - Selector: `0x92041278` 352 | - Contents: 353 | - Currency contract address (`address`) 354 | - Currency amount (`uint256`) 355 | 356 | The magic spend attribute allows for requesting funds from a paymaster during call execution. This can be beneficial to fulfillers as it makes it clear which currencies are needed for call execution and removes the complexity of fulfillers needing to parse the individual calls to determine that for themselves. 357 | 358 | ![image](../assets/rip-7755/call_delivery_magicspend.png "Call delivery with magic spend request") 359 | 360 | This requires access to a paymaster contract that implements the following interface. This likely can only be secure if the paymaster contract is owned by the inbox. 361 | 362 | **Requirements:** 363 | 364 | - Must revert if `fulfiller` has an insufficient balance of `token` in the paymaster 365 | - Must send `amount` of `token` to the `Inbox` contract 366 | 367 | ```solidity 368 | function fulfillerWithdraw(address fulfiller, address token, uint256 amount) external; 369 | ``` 370 | 371 | #### [OPTIONAL] Reward Attribute 372 | 373 | - Selector: `0xa362e5db` 374 | - Contents: 375 | - Asset contract address (`bytes32`) 376 | - Asset amount (`uint256`) 377 | 378 | The reward attribute allows the requester to specify the reward to be locked in the outbox contract as fulfiller compensation. 379 | 380 | #### [OPTIONAL] Inbox Attribute 381 | 382 | - Selector: `0xbd362374` 383 | - Contents: 384 | - Inbox contract address on destination chain (`bytes32`) 385 | 386 | The inbox attribute specifies the contract of the 7755 `Inbox` contract on the destination chain. With standard requests (requests where the payload is an encoded `Call` array), this is not needed since the `receiver` is the `Inbox` contract. However, for cross-chain UserOps, this attribute should be considered required. 387 | 388 | #### [OPTIONAL] Requester Attribute 389 | 390 | - Selector: `0x3bd94e4c` 391 | - Contents: 392 | - Requester address (`bytes32`) 393 | 394 | Allows the requester address to be tied to the 7755 request. 395 | 396 | #### [OPTIONAL] L2 Oracle Attribute 397 | 398 | - Selector: `0x7ff7245a` 399 | - Contents: 400 | - L2 Oracle Address (`address`) 401 | 402 | The L2 Oracle attribute allows the requester to specify the rollup contract address on L1. This is the contract that should be storing state representation for the destination chain and will be used within the settlement layer verification. 403 | 404 | ### Cross-Chain User Operations 405 | 406 | Account abstraction (AA) techniques introduced in ERC-4337 have seen widespread adoption across multiple blockchain networks. This success creates a robust ecosystem that the RRC-7755 standard can leverage to address several challenges - the most important being enabling permissioned cross-chain calls. 407 | 408 | #### UserOp Integration 409 | 410 | If a 7755 request was a 4337 UserOp submitted to the destination chain's `EntryPoint` contract, we solve the `msg.sender` problem since the call execution would route directly through the user's smart account. The caveat here is the 7755 `Inbox` contract then needs to become a 4337 paymaster to: 411 | 412 | 1. Remove the need for the smart account to pay gas for the transaction 413 | 1. Uphold the Inbox contract's core invariant of producing execution receipts when a UserOp succeeds 414 | 415 | For this reason, message payloads can also be an encoded 4337 `UserOp` instead of an encoded `Call` array. If the message is a UserOp, the `receiver` field in the message should point to the destination chain's `EntryPoint` contract, and the Inbox attribute becomes required to specify the destination chain's Inbox contract. 416 | 417 | #### UserOp Attributes and Execution Flow 418 | 419 | When using UserOps, the attributes array in the 7755 message should be empty as the attributes would then be expected to be embedded in the UserOp itself. With that in place, the message ID derivation can borrow existing 4337 UserOp hash derivation mechanisms. 420 | 421 | ![image](../assets/rip-7755/call_delivery_userop.png "Call delivery for a UserOp") 422 | 423 | The execution flow for a UserOp-based cross-chain call is as follows: 424 | 425 | 1. Fulfiller submits UserOp to destination chain `EntryPoint` contract. The UserOp is expected to utilize the 7755 `Paymaster` contract. 426 | 2. `EntryPoint` calls `validateUserOp` in user's Smart Account. 427 | 3. `EntryPoint` calls `validatePaymasterUserOp` in 7755 `Paymaster` contract. The `Paymaster` contract confirms the fulfiller has pre-deposited necessary funds to pay for gas + lend for call execution. 428 | 4. `EntryPoint` calls `exec` in the user's Smart Account to execute the requested calls. 429 | 5. Smart Account calls `withdrawGasExcess` in `Paymaster` if any funds are needed for call execution. 430 | 6. The `Paymaster` will only release approved funds from the validation step. These funds are sent to the Smart Account. 431 | 7. The Smart Account executes requested calls. 432 | 8. `EntryPoint` calls `postOp` in `Paymaster` with the call execution result. 433 | 9. If the call(s) were successful, the `Paymaster` calls into the 7755 `Inbox` contract to create an execution receipt for the request. 434 | 10. The `Inbox` stores the execution receipt in storage. 435 | 436 | #### Paymaster Implementation 437 | 438 | More specifically, within the UserOp, the `paymasterAndData` field must be encoded as follows: 439 | 440 | The first 20 bytes of `paymasterAndData` represent the Paymaster contract address, followed by a 32-byte validation data field, with the remaining bytes containing the encoded 7755 attributes. 441 | 442 | ```solidity 443 | (bytes[] memory attributes) = abi.decode(userOp.paymasterAndData[52:], (bytes[])); 444 | ``` 445 | 446 | The Paymaster contract must also implement the ERC-4337 paymaster interface to validate and pay for UserOps: 447 | 448 | ```solidity 449 | function validatePaymasterUserOp( 450 | UserOperation calldata userOp, 451 | bytes32 userOpHash, 452 | uint256 maxCost 453 | ) external returns (bytes memory context, uint256 validationData); 454 | 455 | function postOp( 456 | PostOpMode mode, 457 | bytes calldata context, 458 | uint256 actualGasCost 459 | ) external; 460 | ``` 461 | 462 | During validation, the Paymaster contract should: 463 | 464 | 1. Decode and validate the attributes from `paymasterAndData` 465 | 1. Optionally verify a precheck condition if the attributes include one 466 | 1. Ensure the fulfiller has pre-deposited enough funds to sponsor the requested calls 467 | 1. After execution, record the fulfillment information in the Inbox storage 468 | 469 | This approach ensures that cross-chain UserOps maintain the same security guarantees as standard 7755 calls while leveraging the account abstraction capabilities of ERC-4337. 470 | 471 | ### Message ID Derivation 472 | 473 | **StandardRequests:** 474 | 475 | ```solidity 476 | keccak256(abi.encode(sourceChain, sender, destinationChain, receiver, payload, attributes)) 477 | ``` 478 | 479 | **UserOpRequests:** 480 | 481 | ```solidity 482 | keccak256(abi.encode(userOp.hash(), receiver.bytes32ToAddress(), uint256(destinationChain))); 483 | ``` 484 | 485 | ## Rationale 486 | 487 | Storage-based proof verification for cross-chain call execution provides cryptographic guarantees without introducing additional trust assumptions beyond Ethereum and its rollups. The Inbox contract's immutable storage design ensures that execution receipts, once stored, remain permanent and verifiable at any future time without increasing proof complexity. 488 | 489 | The standard converts most address types to `bytes32` to maintain forward compatibility, particularly for future non-EVM chain integrations. 490 | 491 | The separation of `rewardAsset` and `rewardAmount` enables support for diverse reward types independent of the cross-chain transaction currency. For instance, while executing a cross-chain transfer of USDC, the reward could be denominated in ETH. The fulfiller must verify that the reward's value adequately compensates for the transaction costs before processing the call. 492 | 493 | The `finalityDelaySeconds` parameter enhances security by ensuring sufficient confidence in destination chain finality before proof submission. This is only relevant if a prover relies on unfinalized state and this security measure can adapt as L1 and L2 consensus mechanisms evolve. 494 | 495 | The `l2Oracle` specification enables proof validation reuse across compatible chains. For instance, multiple OP Stack chains can share a single Outbox contract while maintaining separate `l2Oracle` instances. 496 | 497 | ## Security Considerations 498 | 499 | ### Storage Proof Validation Risks 500 | 501 | Hard forks in any chain can compromise storage proof validation compatibility. This incompatibility may arise from: 502 | 503 | - Changes to the chain's state layout (e.g., migration from Merkle Patricia Trie storage) 504 | - Modifications to L1 data storage mechanisms 505 | 506 | **Critical Impact**: Incompatible storage proof validation can result in locked funds in Outbox contracts. Fulfillers must actively monitor for upcoming hardforks of supported chains. 507 | 508 | ### Fulfiller Risk Management 509 | 510 | The system architecture shifts primary risk exposure from users to fulfillers. Key risks include: 511 | 512 | 1. **Reorg Risk**: Immediate request fulfillment exposes fulfillers to potential source chain reorganizations, which may result in: 513 | 514 | - Transaction reversals 515 | - Token transfer losses 516 | 517 | 2. **Request Validation Requirements** 518 | 519 | At a minimum, fulfillers must validate all requester-set fields against these criteria: 520 | 521 | | Condition | Description | 522 | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 523 | | Confirm the destination chain | Ensure the request's designated destination chain is compatible with the source chain's Outbox. Example: A request originating from an OP Stack outbox and destined for Arbitrum is invalid. | 524 | | Confirm the destination chain receiver | Verify that the request's destination chain receiver is a recognized Inbox or Entrypoint address. | 525 | | Confirm the L2 Oracle | Check that the specified `L2Oracle` is valid for the destination chain. It should be the rollup contract address on Ethereum Mainnet that the destination chain posts state to. | 526 | | Confirm the finality delay | If the finality delay is too short, the requester could reclaim their reward before the state is provable on L1, allowing funds to be effectively stolen. If the delay is too long, the opportunity cost of locked funds becomes high. | 527 | | Confirm the offered compensation | The fulfiller should ensure the reward covers estimated gas costs for submitting the request on the destination chain, estimated gas costs for proving the request and claiming the reward on the source chain, any required funds for execution on the destination chain, and the opportunity cost of locked funds during the finality delay | 528 | | Validate UserOp | If the request is a UserOp, ensure the paymaster address is a recognized 7755 paymaster | 529 | | Confirm fulfiller funding | The fulfiller should confirm it has sufficient balances to cover all funds needed for destination chain call execution | 530 | 531 | ## Copyright 532 | 533 | Copyright and related rights waived via [CC0](../LICENSE.md). 534 | -------------------------------------------------------------------------------- /RIPS/rip-7767.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7767 3 | title: Gas to Ether contract 4 | description: A contract that burns gas and returns a portion of the gas burned to the caller as Ether 5 | author: Vectorized (@Vectorized), Mark Tyneway (@tynes), Zak Cole (@zscole), Charles Cooper (@charles-cooper) 6 | discussions-to: https://ethereum-magicians.org/t/rip-7767-gas-to-ether-precompile/21005 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2024-09-12 11 | --- 12 | 13 | ## Abstract 14 | 15 | This proposal describes a contract that allows the caller to burn a specific amount of gas, and returns a portion of the gas burned to the caller as Ether. 16 | 17 | ## Motivation 18 | 19 | Contract Secured Revenue (CSR) enables contract developers to earn gas fees on their contracts. 20 | 21 | It enables new revenue streams in a composable, interoperable, enforceable way. CSR works with any existing token standard and applications. It does not require developers to break or create new contract standards for the sake of capturing value. 22 | 23 | However, implicit CSR which is metered by gas spent on every opcode can lead to negative externalities. Developers are incentivized to write bloated contracts, such as using a loop to perform unnecessary storage writes and compute. 24 | 25 | This standard proposes making CSR explicit with a special contract, `GASBACK`, which converts burned gas into Ether with a constant cost. Developers are incentivized to write efficient contracts, so that they can have more gas room to use for `GASBACK`. 26 | 27 | `GASBACK` offers the following advantages: 28 | - Composability, since Ether is to be paid back immediately to the caller. Also, `GASBACK` provides a standardized interface for explicit CSR, enabling reusable integration code in tooling and applications. 29 | - Permissionlessness, since contracts integrating `GASBACK` do not need to be vetted by a centralized team to ensure that they are not intentionally writing bloated code. 30 | - Transparency, since `GASBACK` can be implemented in Solidity with verified code. This gives developers better clarity and confidence over traditional implicit CSR operated by opaque CRON jobs. 31 | - Maintainability, since `GASBACK` is simple and flexible. 32 | - Usability, since the gas burned in `GASBACK` can be easily segmented from regular gas. 33 | 34 | ## Specification 35 | 36 | We will refer to this contract as the `GASBACK` contract. 37 | 38 | ### Behavior 39 | 40 | The `GASBACK` contract takes in calldata `bytes32(uint256(gasToBurn))`. 41 | 42 | The actual amount of gas burned may vary but SHOULD be proportional to `gasToBurn`. 43 | 44 | The `GASBACK` contract MUST be `O(1)` in state and compute costs with respect to `gasToBurn`. 45 | 46 | The `GASBACK` contract SHOULD give the caller a fraction of the gas burned back as Ether (or native currency). 47 | 48 | The `GASBACK` contract SHOULD do a best-effort transfer of Ether to the caller. If transferring Ether with a `call` fails, the `GASBACK` contract MAY create a new contract that use the `SELFDESTRUCT` opcode to force-transfer the Ether. 49 | 50 | The `GASBACK` contract MUST return `bytes32(uint256(amountOfEtherGivenBackToCaller))`. 51 | 52 | The amount of Ether obtained from the burned gas MUST not exceed `basefee * actualGasBurned`. 53 | 54 | The gas burned in `GASBACK` MAY be excluded from [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) and block gas limits. 55 | 56 | `GASBACK` can co-exist with traditional implicit CSR, but it is RECOMMENDED for chains to fully migrate to `GASBACK` if possible for maximum benefits. 57 | 58 | ### Beacon 59 | 60 | To support a variety of L2 implementations, there is no designated address for the `GASBACK` contract. 61 | 62 | Chains implementing `GASBACK` SHOULD include its address in their documentation. 63 | 64 | To facilitate onchain discovery, we designate a canonical beacon contract deployed by Nick's `CREATE2` factory. This beacon contract returns `abi.encode(gasbackAddress)` when called. 65 | 66 | ```solidity 67 | // SPDX-License-Identifier: CC0-1.0 68 | pragma solidity ^0.8.28; 69 | 70 | // solc = 0.8.28, evm = london, optimization = 1000. 71 | contract GasbackBeacon { 72 | fallback() external payable { 73 | assembly { 74 | mstore(0x40, sload(returndatasize())) 75 | if xor(caller(), 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE) { return(0x40, 0x20) } 76 | sstore(returndatasize(), calldataload(returndatasize())) 77 | } 78 | } 79 | } 80 | ``` 81 | 82 | Final address of the beacon contract TBD. 83 | 84 | Implementation of the `GASBACK` beacon contract is OPTIONAL, as some chains do not support `CREATE2` deployments. 85 | 86 | ## Rationale 87 | 88 | `GASBACK` can be implemented as a preinstall, predeploy, precompile. 89 | 90 | On the Optimism stack, it is possible to implement `GASBACK` as a predeploy without modifying the client. 91 | 92 | The behavior is deliberately kept simple and flexible so that `GASBACK` can be implemented in the most suitable way for each EVM chain. 93 | 94 | ## Security Considerations 95 | 96 | Implementers must make sure that the precompile does not cause a net increase in the total amount of Ether on the network. 97 | 98 | EVM chains hosting any retroactive funding based on gas burned metrics should subtract the total amount of gas burned via the `GASBACK` precompile. 99 | 100 | ## Copyright 101 | 102 | Copyright and related rights waived via [CC0](../LICENSE.md). 103 | -------------------------------------------------------------------------------- /RIPS/rip-7810.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7810 3 | title: RIP Purpose and Guidelines 4 | status: Living 5 | type: Meta 6 | author: Nicolas Consigny , Carl Beekhuizen , Ansgar Dietrichs , Yoav Weiss 7 | created: 2024-11-08 8 | --- 9 | ## What is an RIP? 10 | RIP stands for Rollup Improvement Proposal. Akin to EIPs, RIPs are specification documents providing information to the Ethereum and rollups communities, or describing a new feature for rollups or their processes or environment. An RIP should provide a concise technical specification of the feature and a rationale for the feature. The RIP author is responsible for building consensus within the community. RIPs offer optional standards for RollUps, L2s, and EVM-equivalent-chains to opt into should they wish to leverage interoperability. Engaging in this process is strongly encouraged for those to whom it is relevant, as it aligns with a shared open-source development approach that promotes collaboration and transparency 11 | 12 | ## RIP Rationale 13 | 14 | RIPs are intended to be the primary mechanism for proposing new features, for collecting community technical input on an issue, and for documenting some of the design decisions that have gone into Ethereum's rollups. Thus RIPs help to coordinate a shared improvement process for rollups. Because the RIPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal. 15 | 16 | For rollups that are multiclients, RIPs are a convenient way to track the progress of their implementation. In the case of a multi client rollup, ideally, each implementation maintainer would list the RIPS and EIPs that they have implemented. End users can refer to external sources such as rollup.codes to track the differences between rollups and the Ethereum mainnet. 17 | 18 | ## RIP Types 19 | There are three types of RIP: 20 | 21 | - **A Standards Track RIP** describes any change that MAY affect most or all rollups' implementations, such as—a change to the network protocol, a change in block or transaction validity rules, proposed application standards/conventions, or any change or addition that affects the interoperability of applications using rollups. Standards Track RIPs consist of three parts—a design document, an implementation, and (if warranted) an update to the formal specification. Furthermore, Standards Track RIPs can be broken down into the following categories: 22 | 23 | - *Core*: improvements that would be requiring a consensus fork such as, block or transaction validity rules, EVM opcodes modifications, cryptographic primitives updates, precompiled contracts (e.g. [RIP-7728](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7728.md)), gas costs etc. 24 | - *RRC*: (Rollup Request for Comments) application-level standards and conventions, including contract standards such as token standards, name registries, URI schemes, library/package formats, and wallet formats, that would not be relevant in the L1 context (e.g [RRC-7755](https://github.com/ethereum/RIPs/pull/31/files)). If an application-level standard or convention is relevant in the layer 1 context it should be an ERC and should not be duplicated as an RRC. 25 | - *Other* : other improvements that are relevant to core dev discussions. 26 | 27 | 28 | - A **Meta RIP** describes a process surrounding Ethereum's rollups or proposes a change to (or an event in) a process. Process RIPs are like Standards Track RIPs but apply to areas other than the Ethereum protocol itself. They may propose an implementation, but not to rollups' codebase; they often require community consensus; they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Ethereum development. Any meta-RIP is also considered a Process RIP. 29 | 30 | It is highly recommended that a single RIP contain a single key proposal or new idea. The more focused the RIP, the more successful it tends to be. 31 | 32 | An RIP must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly. 33 | 34 | 35 | ### Special requirements for Core RIPs 36 | 37 | If an RIP mentions or proposes changes to the EVM, it should refer to the instructions by their mnemonics and define the opcodes of those mnemonics at least once. The L1 opcodes should be used and MUST take priority if a conflict arises. A preferred way is the following: 38 | 39 | ``` 40 | REVERT (0xfe) 41 | ``` 42 | ## RIP Work Flow 43 | 44 | ### Shepherding an RIP 45 | 46 | Parties involved in the process are you, the champion or *RIP author*, the [*RIP editors*](#rip-editors), the [*rollups core teams*](https://l2beat.com/scaling/summary) and the [*Ethereum Core Developers*](https://github.com/ethereum/pm). 47 | 48 | Before you begin writing a formal RIP, you should vet your idea. Ask the Ethereum community first if an idea is original to avoid wasting time on something that will be rejected based on prior research. It is thus recommended to open a discussion thread on the [Ethereum Magicians forum - RIP category](https://ethereum-magicians.org/c/rips/58) to do this. 49 | 50 | Once the idea has been vetted, your next responsibility will be to present (by means of an RIP) the idea to the reviewers and all interested parties, invite editors, developers, and the community to give feedback on the aforementioned channels. You should try and gauge whether the interest in your RIP is commensurate with both the work involved in implementing it and how many parties will have to conform to it. For example, the work required for implementing a Core RIP will be much greater than for an RRC and the RIP will need sufficient interest from the Ethereum's rollups core teams. 51 | 52 | ### Core RIPs 53 | 54 | For Core RIPs, an author needs to convince [*rollups core teams*](https://l2beat.com/scaling/summary) to implement your RIP. 55 | 56 | The best way to get rollups core teams to review your RIP is to present it on a Rollcall. You can request to do so by posting a comment linking your RIP on an [Rollcall agenda - GitHub issue](https://github.com/ethereum/pm/issues). 57 | 58 | The Rollcall serves as a way for rollups teams to discuss the technical merits and tradeoffs of various RIPs and to gauge what other rollups will be implementing. 59 | 60 | These calls generally result in a "rough consensus" around what RIPs should be included in the L2 core specification. This "rough consensus" rests on the assumptions that RIPs are not conflicting and can be included in the specification behind feature flags and that they are technically sound. 61 | 62 | :warning: If you are shepherding an RIP, you can make the process of building community consensus easier by making sure that [the Ethereum Magicians forum](https://ethereum-magicians.org/) thread for your RIP includes or links to as much of the community discussion as possible and that various rollups core teams are well-represented in those. 63 | 64 | *In short, your role as the champion is to write the RIP using the style and format described below, shepherd the discussions in the appropriate forums, and build community consensus around the idea.* 65 | 66 | ### RIP Process 67 | 68 | The following is the standardization process for all RIPs in all tracks: 69 | 70 | ![RIP RIP_process](../assets/rip-7810/RIP_process.png) 71 | 72 | 73 | **Idea** - An idea that is pre-draft. This is not tracked within the RIP Repository. 74 | 75 | **Draft** - The first formally tracked stage of an RIP in development. An RIP is merged by an RIP Editor into the RIP repository when properly formatted. 76 | 77 | **Review** - An RIP Author marks an RIP as ready to implement and requesting Peer Review. 78 | 79 | **Final** - This RIP represents the final standard. A Final RIP exists in a state of finality and should only be updated to correct errata and add non-normative clarifications.An RIP is considered final as soon as one rollup implements and deploys it to their mainnet. Care should be taken to resolve discussions & conflicts before deploying to mainnet as unresolved issues could result in a second (competing) standard emerging. 80 | 81 | 82 | **Stagnant** - Any RIP in `Draft` or `Review` if inactive for a period of 6 months or greater is moved to `Stagnant`. An RIP may be resurrected from this state by Authors or RIP Editors through moving it back to `Draft` or its earlier status. If not resurrected, a proposal may stay forever in this status. 83 | 84 | >*RIP Authors are notified of any algorithmic change to the status of their RIP* 85 | 86 | **Withdrawn** - The RIP Author(s) have withdrawn the proposed RIP. This state has finality and can no longer be resurrected using this RIP number. If the idea is pursued at later date it is considered a new proposal. 87 | 88 | **Living** - A special status for RIPs that are designed to be continually updated and not reach a state of finality. This includes most notably the present document. 89 | 90 | ## What belongs in a successful RIP? 91 | 92 | Championing an RIP can be challenging due to the involvement of multiple stakeholders resulting from the plurality of rollups. One way to overcome this is to involve multiple rollups as early as possible in the discussion. Ideally, an author can co-write RIPs with multiple teams and ensure that the corresponding rollups are engaged. 93 | 94 | Each RIP should have the following parts: 95 | 96 | - Preamble - [RFC-822](https://www.w3.org/Protocols/rfc822/) style headers containing metadata about the RIP, including the RIP number, a short descriptive title (limited to a maximum of 44 characters), a description (limited to a maximum of 140 characters), and the author details. Irrespective of the category, the title and description should not include RIP number. See [below](./rip-1.md#rip-header-preamble) for details. 97 | - Abstract - Abstract is a multi-sentence (short paragraph) technical summary. This should be a very terse and human-readable version of the specification section. Someone should be able to read only the abstract to get the gist of what this specification does. 98 | - Motivation *(optional)* - A motivation section is critical for RIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the RIP solves. This section may be omitted if the motivation is evident. 99 | - Specification - The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any EVM/execution-layer platform. 100 | - Rationale - The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale should discuss important objections or concerns raised during discussion around the RIP. 101 | - Backwards Compatibility *(optional)* - All RIPs that introduce backwards incompatibilities with the Ethereum mainnet must include a section describing these incompatibilities and their consequences. If a proposal introduces backwards incompatibilities with multiple RIPs specified in this document, it must explain how the author proposes to deal with these incompatibilities. This section may be omitted if the proposal does not introduce backwards incompatibilities or incompatibilities between rollups. 102 | - Test Cases *(optional)* - Test cases for an implementation are mandatory for RIPs that are affecting consensus changes. Tests should either be inlined in the RIP as data (such as input/expected output pairs, or included in `../assets/rip-###/`. This section may be omitted for non-Core proposals. 103 | - Reference Implementation *(optional)* - An optional section that contains a reference/example implementation that people can use to assist in understanding or implementing this specification. This section may be omitted for all RIPs. 104 | - Security Considerations - All RIPs must contain a section that discusses the security implications/considerations relevant to the proposed change. Include information that might be important for security discussions, surfaces risks and can be used throughout the life-cycle of the proposal. E.g. include security-relevant design decisions, concerns, important discussions, implementation-specific guidance and pitfalls, an outline of threats and risks and how they are being addressed. RIP submissions missing the "Security Considerations" section will be rejected. An RIP cannot proceed to status "Final" without a Security Considerations discussion deemed sufficient by the reviewers. 105 | - Copyright Waiver - All RIPs must be in the public domain. The copyright waiver MUST link to the license file and use the following wording: `Copyright and related rights waived via [CC0](../LICENSE.md).` 106 | 107 | 108 | 109 | ## RIP Formats and Templates 110 | 111 | RIPs should be written in [markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) format. There is a [template](https://github.com/ethereum/EIPs/blob/master/eip-template.md) to follow. 112 | 113 | ## RIP Header Preamble 114 | 115 | Each RIP must begin with an [RFC 822](https://www.ietf.org/rfc/rfc822.txt) style header preamble, preceded and followed by three hyphens (`---`). This header is also termed ["front matter" by Jekyll](https://jekyllrb.com/docs/front-matter/). The headers must appear in the following order. 116 | 117 | `rip`: *RIP number* 118 | 119 | `title`: *The RIP title is a few words, not a complete sentence* 120 | 121 | `description`: *Description is one full (short) sentence* 122 | 123 | `author`: *The list of the author's or authors' name(s) and/or username(s), or name(s) and email(s). Details are below.* 124 | 125 | `discussions-to`: *The url pointing to the official discussion thread* 126 | 127 | `status`: *Draft, Review, Final, Living, Stagnant, Withdrawn* 128 | 129 | `type`: *One of `Standards Track` or `Meta`* 130 | 131 | `category`: *One of `Core`, `RRC`, or `Other`* (Optional field, only needed for `Standards Track` RIPs) 132 | 133 | `created`: *Date the RIP was created on* 134 | 135 | `requires`: *RIP number(s)* (Optional field) 136 | 137 | `withdrawal-reason`: *A sentence explaining why the RIP was withdrawn.* (Optional field, only needed when status is `Withdrawn`) 138 | 139 | Headers that permit lists must separate elements with commas. 140 | 141 | Headers requiring dates will always do so in the format of ISO 8601 (yyyy-mm-dd). 142 | 143 | ### `author` header 144 | 145 | The `author` header lists the names, email addresses or usernames of the authors/owners of the RIP. Those who prefer anonymity may use a username only, or a first name and a username. The format of the `author` header value must be: 146 | 147 | > Random J. User <address@dom.ain> 148 | 149 | or 150 | 151 | > Random J. User (@username) 152 | 153 | or 154 | 155 | > Random J. User (@username) <address@dom.ain> 156 | 157 | if the email address and/or GitHub username is included, and 158 | 159 | > Random J. User 160 | 161 | if neither the email address nor the GitHub username are given. 162 | 163 | At least one author must use a GitHub username, in order to get notified on change requests and have the capability to approve or reject them. 164 | 165 | ### `discussions-to` header 166 | 167 | While an RIP is a draft, a `discussions-to` header will indicate the URL where the RIP is being discussed. 168 | 169 | The preferred discussion URL is a topic on [Ethereum Magicians](https://ethereum-magicians.org/). The URL cannot point to Github pull requests, any URL which is ephemeral, and any URL which can get locked over time (i.e. Reddit topics). 170 | 171 | ### `type` header 172 | 173 | The `type` header specifies the type of RIP: Standards Track or Meta. If the track is Standards please include the subcategory (core, other or RRC). 174 | 175 | ### `category` header 176 | 177 | The `category` header specifies the RIP's category. This is required for standards-track RIPs only. 178 | 179 | ### `created` header 180 | 181 | The `created` header records the date that the RIP was assigned a number. Both headers should be in yyyy-mm-dd format, e.g. 2001-08-14. 182 | 183 | ### `requires` header 184 | 185 | RIPs may have a `requires` header, indicating the RIP numbers that this RIP depends on. If such a dependency exists, this field is required. 186 | 187 | A `requires` dependency is created when the current RIP cannot be understood or implemented without a concept or technical element from another RIP. Merely mentioning another RIP does not necessarily create such a dependency. 188 | 189 | ## Linking to External Resources 190 | 191 | Other than the specific exceptions listed below, links to external resources **SHOULD NOT** be included. External resources may disappear, move, or change unexpectedly. 192 | 193 | 194 | 195 | ### Execution Client Specifications 196 | 197 | Links to the Ethereum Execution Client Specifications may be included using normal markdown syntax, such as: 198 | 199 | ```markdown 200 | [Ethereum Execution Client Specifications](https://github.com/ethereum/execution-specs/blob/9a1f22311f517401fed6c939a159b55600c454af/README.md) 201 | ``` 202 | 203 | Which renders to: 204 | 205 | [Ethereum Execution Client Specifications](https://github.com/ethereum/execution-specs/blob/9a1f22311f517401fed6c939a159b55600c454af/README.md) 206 | 207 | Permitted Execution Client Specifications URLs must anchor to a specific commit, and so must match this regular expression: 208 | 209 | ```regex 210 | ^(https://github.com/ethereum/execution-specs/(blob|commit)/[0-9a-f]{40}/.*|https://github.com/ethereum/execution-specs/tree/[0-9a-f]{40}/.*)$ 211 | ``` 212 | 213 | ### Execution Specification Tests 214 | 215 | Links to the Ethereum Execution Specification Tests (EEST) may be included using normal markdown syntax, such as: 216 | 217 | ```markdown 218 | [Ethereum Execution Specification Tests](https://github.com/ethereum/execution-spec-tests/blob/c9b9307ff320c9bb0ecb9a951aeab0da4d9d1684/README.md) 219 | ``` 220 | 221 | Which renders to: 222 | 223 | [Ethereum Execution Specification Tests](https://github.com/ethereum/execution-spec-tests/blob/c9b9307ff320c9bb0ecb9a951aeab0da4d9d1684/README.md) 224 | 225 | Permitted Execution Specification Tests URLs must anchor to a specific commit, and so must match one of these regular expressions: 226 | 227 | ```regex 228 | ^https://(www\.)?github\.com/ethereum/execution-spec-tests/(blob|tree)/[a-f0-9]{40}/.+$ 229 | ``` 230 | 231 | ```regex 232 | ^https://(www\.)?github\.com/ethereum/execution-spec-tests/commit/[a-f0-9]{40}$ 233 | ``` 234 | 235 | ### Consensus Layer Specifications 236 | 237 | Links to specific commits of files within the Ethereum Consensus Layer Specifications may be included using normal markdown syntax, such as: 238 | 239 | ```markdown 240 | [Beacon Chain](https://github.com/ethereum/consensus-specs/blob/26695a9fdb747ecbe4f0bb9812fedbc402e5e18c/specs/sharding/beacon-chain.md) 241 | ``` 242 | 243 | Which renders to: 244 | 245 | [Beacon Chain](https://github.com/ethereum/consensus-specs/blob/26695a9fdb747ecbe4f0bb9812fedbc402e5e18c/specs/sharding/beacon-chain.md) 246 | 247 | Permitted Consensus Layer Specifications URLs must anchor to a specific commit, and so must match this regular expression: 248 | 249 | ```regex 250 | ^https://github.com/ethereum/consensus-specs/(blob|commit)/[0-9a-f]{40}/.*$ 251 | ``` 252 | 253 | ### Networking Specifications 254 | 255 | Links to specific commits of files within the Ethereum Networking Specifications may be included using normal markdown syntax, such as: 256 | 257 | ```markdown 258 | [Ethereum Wire Protocol](https://github.com/ethereum/devp2p/blob/40ab248bf7e017e83cc9812a4e048446709623e8/caps/eth.md) 259 | ``` 260 | 261 | Which renders as: 262 | 263 | [Ethereum Wire Protocol](https://github.com/ethereum/devp2p/blob/40ab248bf7e017e83cc9812a4e048446709623e8/caps/eth.md) 264 | 265 | Permitted Networking Specifications URLs must anchor to a specific commit, and so must match this regular expression: 266 | 267 | ```regex 268 | ^https://github.com/ethereum/devp2p/(blob|commit)/[0-9a-f]{40}/.*$ 269 | ``` 270 | 271 | ### Portal Specifications 272 | 273 | Links to specific commits of files within the Ethereum Portal Specifications may be included using normal markdown syntax, such as: 274 | 275 | ```markdown 276 | [Portal Wire Protocol](https://github.com/ethereum/portal-network-specs/blob/5e321567b67bded7527355be714993c24371de1a/portal-wire-protocol.md) 277 | ``` 278 | 279 | Which renders as: 280 | 281 | [Portal Wire Protocol](https://github.com/ethereum/portal-network-specs/blob/5e321567b67bded7527355be714993c24371de1a/portal-wire-protocol.md) 282 | 283 | Permitted Networking Specifications URLs must anchor to a specific commit, and so must match this regular expression: 284 | 285 | ```regex 286 | ^https://github.com/ethereum/portal-network-specs/(blob|commit)/[0-9a-f]{40}/.*$ 287 | ``` 288 | 289 | ### World Wide Web Consortium (W3C) 290 | 291 | Links to a W3C "Recommendation" status specification may be included using normal markdown syntax. For example, the following link would be allowed: 292 | 293 | ```markdown 294 | [Secure Contexts](https://www.w3.org/TR/2021/CRD-secure-contexts-20210918/) 295 | ``` 296 | 297 | Which renders as: 298 | 299 | [Secure Contexts](https://www.w3.org/TR/2021/CRD-secure-contexts-20210918/) 300 | 301 | Permitted W3C recommendation URLs MUST anchor to a specification in the technical reports namespace with a date, and so MUST match this regular expression: 302 | 303 | ```regex 304 | ^https://www\.w3\.org/TR/[0-9][0-9][0-9][0-9]/.*$ 305 | ``` 306 | 307 | ### Web Hypertext Application Technology Working Group (WHATWG) 308 | 309 | Links to WHATWG specifications may be included using normal markdown syntax, such as: 310 | 311 | ```markdown 312 | [HTML](https://html.spec.whatwg.org/commit-snapshots/578def68a9735a1e36610a6789245ddfc13d24e0/) 313 | ``` 314 | 315 | Which renders as: 316 | 317 | [HTML](https://html.spec.whatwg.org/commit-snapshots/578def68a9735a1e36610a6789245ddfc13d24e0/) 318 | 319 | Permitted WHATWG specification URLs must anchor to a specification defined in the `spec` subdomain (idea specifications are not allowed) and to a commit snapshot, and so must match this regular expression: 320 | 321 | ```regex 322 | ^https:\/\/[a-z]*\.spec\.whatwg\.org/commit-snapshots/[0-9a-f]{40}/$ 323 | ``` 324 | 325 | Although not recommended by WHATWG, RIPs must anchor to a particular commit so that future readers can refer to the exact version of the living standard that existed at the time the RIP was finalized. This gives readers sufficient information to maintain compatibility, if they so choose, with the version referenced by the RIP and the current living standard. 326 | 327 | ### Internet Engineering Task Force (IETF) 328 | 329 | Links to an IETF Request For Comment (RFC) specification may be included using normal markdown syntax, such as: 330 | 331 | ```markdown 332 | [RFC 8446](https://www.rfc-editor.org/rfc/rfc8446) 333 | ``` 334 | 335 | Which renders as: 336 | 337 | [RFC 8446](https://www.rfc-editor.org/rfc/rfc8446) 338 | 339 | Permitted IETF specification URLs MUST anchor to a specification with an assigned RFC number (meaning cannot reference internet drafts), and so MUST match this regular expression: 340 | 341 | ```regex 342 | ^https:\/\/www.rfc-editor.org\/rfc\/.*$ 343 | ``` 344 | 345 | ### Bitcoin Improvement Proposal 346 | 347 | Links to Bitcoin Improvement Proposals may be included using normal markdown syntax, such as: 348 | 349 | ```markdown 350 | [BIP 38](https://github.com/bitcoin/bips/blob/3db736243cd01389a4dfd98738204df1856dc5b9/bip-0038.mediawiki) 351 | ``` 352 | 353 | Which renders to: 354 | 355 | [BIP 38](https://github.com/bitcoin/bips/blob/3db736243cd01389a4dfd98738204df1856dc5b9/bip-0038.mediawiki) 356 | 357 | Permitted Bitcoin Improvement Proposal URLs must anchor to a specific commit, and so must match this regular expression: 358 | 359 | ```regex 360 | ^(https://github.com/bitcoin/bips/blob/[0-9a-f]{40}/bip-[0-9]+\.mediawiki)$ 361 | ``` 362 | 363 | ### National Vulnerability Database (NVD) 364 | 365 | Links to the Common Vulnerabilities and Exposures (CVE) system as published by the National Institute of Standards and Technology (NIST) may be included, provided they are qualified by the date of the most recent change, using the following syntax: 366 | 367 | ```markdown 368 | [CVE-2023-29638 (2023-10-17T10:14:15)](https://nvd.nist.gov/vuln/detail/CVE-2023-29638) 369 | ``` 370 | 371 | Which renders to: 372 | 373 | [CVE-2023-29638 (2023-10-17T10:14:15)](https://nvd.nist.gov/vuln/detail/CVE-2023-29638) 374 | 375 | ### Chain Agnostic Improvement Proposals (CAIPs) 376 | 377 | Links to a Chain Agnostic Improvement Proposals (CAIPs) specification may be included using normal markdown syntax, such as: 378 | 379 | ```markdown 380 | [CAIP 10](https://github.com/ChainAgnostic/CAIPs/blob/5dd3a2f541d399a82bb32590b52ca4340b09f08b/CAIPs/caip-10.md) 381 | ``` 382 | 383 | Which renders to: 384 | 385 | [CAIP 10](https://github.com/ChainAgnostic/CAIPs/blob/5dd3a2f541d399a82bb32590b52ca4340b09f08b/CAIPs/caip-10.md) 386 | 387 | Permitted Chain Agnostic URLs must anchor to a specific commit, and so must match this regular expression: 388 | 389 | ```regex 390 | ^(https://github.com/ChainAgnostic/CAIPs/blob/[0-9a-f]{40}/CAIPs/caip-[0-9]+\.md)$ 391 | ``` 392 | 393 | ### Ethereum Yellow Paper 394 | 395 | Links to the Ethereum Yellow Paper may be included using normal markdown syntax, such as: 396 | 397 | ```markdown 398 | [Ethereum Yellow Paper](https://github.com/ethereum/yellowpaper/blob/9c601d6a58c44928d4f2b837c0350cec9d9259ed/paper.pdf) 399 | ``` 400 | 401 | Which renders to: 402 | 403 | [Ethereum Yellow Paper](https://github.com/ethereum/yellowpaper/blob/9c601d6a58c44928d4f2b837c0350cec9d9259ed/paper.pdf) 404 | 405 | Permitted Yellow Paper URLs must anchor to a specific commit, and so must match this regular expression: 406 | 407 | ```regex 408 | ^(https://github\.com/ethereum/yellowpaper/blob/[0-9a-f]{40}/paper\.pdf)$ 409 | ``` 410 | 411 | ### Execution Client Specification Tests 412 | 413 | Links to the Ethereum Execution Client Specification Tests may be included using normal markdown syntax, such as: 414 | 415 | ```markdown 416 | [Ethereum Execution Client Specification Tests](https://github.com/ethereum/execution-spec-tests/blob/d5a3188f122912e137aa2e21ed2a1403e806e424/README.md) 417 | ``` 418 | 419 | Which renders to: 420 | 421 | [Ethereum Execution Client Specification Tests](https://github.com/ethereum/execution-spec-tests/blob/d5a3188f122912e137aa2e21ed2a1403e806e424/README.md) 422 | 423 | Permitted Execution Client Specification Tests URLs must anchor to a specific commit, and so must match this regular expression: 424 | 425 | ```regex 426 | ^(https://github.com/ethereum/execution-spec-tests/(blob|commit)/[0-9a-f]{40}/.*|https://github.com/ethereum/execution-spec-tests/tree/[0-9a-f]{40}/.*)$ 427 | ``` 428 | ### Rollup codes 429 | 430 | Links to the website rollup.codes may be included, using normal markdown syntax, such as: 431 | 432 | ```markdown 433 | [rollup.codes](https://www.rollup.codes/) 434 | ``` 435 | 436 | Which renders to: 437 | 438 | [rollup.codes](https://www.rollup.codes/) 439 | 440 | ### L2BEAT 441 | 442 | Links to the website rollup.codes may be included, using normal markdown syntax, such as: 443 | 444 | ```markdown 445 | [L2BEAT](https://l2beat.com/scaling/summary) 446 | ``` 447 | 448 | Which renders to: 449 | 450 | [L2BEAT](https://l2beat.com/scaling/summary) 451 | 452 | ### Digital Object Identifier System 453 | 454 | Links qualified with a Digital Object Identifier (DOI) may be included using the following syntax: 455 | 456 | ````markdown 457 | This is a sentence with a footnote.[^1] 458 | 459 | [^1]: 460 | ```csl-json 461 | { 462 | "type": "article", 463 | "id": 1, 464 | "author": [ 465 | { 466 | "family": "Sovereign", 467 | "given": "Rollup" 468 | } 469 | ], 470 | "DOI": "00.0000/a00000-000-0000-y", 471 | "title": "An Interesting Article", 472 | "original-date": { 473 | "date-parts": [ 474 | [2022, 12, 31] 475 | ] 476 | }, 477 | "URL": "https://sly-hub.invalid/00.0000/a00000-000-0000-y", 478 | "custom": { 479 | "additional-urls": [ 480 | "https://example.com/an-interesting-article.pdf" 481 | ] 482 | } 483 | } 484 | ``` 485 | ```` 486 | 487 | Which renders to: 488 | 489 | 490 | 491 | 492 | This is a sentence with a footnote.[^1] 493 | 494 | [^1]: 495 | ```csl-json 496 | { 497 | "type": "article", 498 | "id": 1, 499 | "author": [ 500 | { 501 | "family": "Sovereign", 502 | "given": "Rollup" 503 | } 504 | ], 505 | "DOI": "00.0000/a00000-000-0000-y", 506 | "title": "An Interesting Article", 507 | "original-date": { 508 | "date-parts": [ 509 | [2022, 12, 31] 510 | ] 511 | }, 512 | "URL": "https://sly-hub.invalid/00.0000/a00000-000-0000-y", 513 | "custom": { 514 | "additional-urls": [ 515 | "https://example.com/an-interesting-article.pdf" 516 | ] 517 | } 518 | } 519 | ``` 520 | 521 | 522 | 523 | See the [Citation Style Language Schema](https://resource.citationstyles.org/schema/v1.0/input/json/csl-data.json) for the supported fields. In addition to passing validation against that schema, references must include a DOI and at least one URL. 524 | 525 | The top-level URL field must resolve to a copy of the referenced document which can be viewed at zero cost. Values under `additional-urls` must also resolve to a copy of the referenced document, but may charge a fee. 526 | 527 | ## Linking to other RIPs or EIPs 528 | 529 | References to other RIPs or EIPs should follow the format `RIP-N` where `N` is the RIP number you are referring to. Each RIP or EIP that is referenced in an RIP **MUST** be accompanied by a relative markdown link the first time it is referenced, and **MAY** be accompanied by a link on subsequent references. The link **MUST** always be done via relative paths so that the links work in this GitHub repository, forks of this repository, the main EIPs site, mirrors of the main RIP site, etc. For example, you would link to this RIP as `./rip-1.md`. 530 | 531 | ## Auxiliary Files 532 | 533 | Images, diagrams and auxiliary files should be included in a subdirectory of the `assets` folder for that RIP as follows: `assets/rip-N` (where **N** is to be replaced with the RIP number). When linking to an image in the RIP, use relative links such as `../assets/rip-1/image.png`. 534 | 535 | ## Transferring RIP Ownership 536 | 537 | It occasionally becomes necessary to transfer ownership of RIPs to a new champion. In general, we'd like to retain the original author as a co-author of the transferred RIP, but that's really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the RIP process, or has fallen off the face of the 'net (i.e. is unreachable or isn't responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the RIP. We try to build consensus around an RIP, but if that's not possible, you can always submit a competing RIP. 538 | 539 | If you are interested in assuming ownership of an RIP, send a message asking to take over, addressed to both the original author and the RIP editor. If the original author doesn't respond to the email in a timely manner, the RIP editor will make a unilateral decision (it's not like such decisions can't be reversed :)). 540 | 541 | ## RIP Editors 542 | 543 | The current RIP editors are 544 | 545 | - Ansgar Dietrichs 546 | - Carl Beekhuizen 547 | - Yoav Weiss 548 | - Nicolas Consigny 549 | 550 | ## RIP Editor Responsibilities 551 | 552 | For each new RIP that comes in, an editor does the following: 553 | 554 | - Read the RIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don't seem likely to get to final status. 555 | - The title should accurately describe the content. 556 | - Check the RIP for language (spelling, grammar, sentence structure, etc.), markup (GitHub flavored Markdown), code style 557 | 558 | If the RIP isn't ready, the editor will send it back to the author for revision, with specific instructions. 559 | 560 | Once the RIP is ready for the repository, the RIP editor will: 561 | 562 | - Assign an RIP number (generally incremental; editors can reassign if number sniping is suspected) 563 | - Merge the corresponding [pull request](https://github.com/ethereum/RIPs/pulls) 564 | - Send a message back to the RIP author with the next step. 565 | 566 | The editors don't pass judgment on RIPs. They merely do the administrative & editorial part. 567 | 568 | ## Style Guide 569 | 570 | ### Titles 571 | 572 | The `title` field in the preamble: 573 | 574 | - Should not include the word "standard" or any variation thereof; and 575 | - Should not include the RIP's number. 576 | 577 | ### Descriptions 578 | 579 | The `description` field in the preamble: 580 | 581 | - Should not include the word "standard" or any variation thereof; and 582 | - Should not include the RIP's number. 583 | 584 | ### RIP numbers 585 | 586 | When referring to an RIP with a `category` of `RRC`, it must be written in the hyphenated form `RRC-X` where `X` is that RIP's assigned number. When referring to RIPs with any other `category`, it must be written in the hyphenated form `RIP-X` where `X` is that RIP's assigned number. 587 | 588 | ### RFC 2119 and RFC 8174 589 | 590 | RIPs are encouraged to follow [RFC 2119](https://www.ietf.org/rfc/rfc2119.html) and [RFC 8174](https://www.ietf.org/rfc/rfc8174.html) for terminology and to insert the following at the beginning of the Specification section: 591 | 592 | > The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. 593 | 594 | ## History 595 | 596 | This document was inspired from [EIP-1](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1.md) written by Martin Becze, Hudson Jameson et al. Which was derived heavily from [Bitcoin's BIP-0001](https://github.com/bitcoin/bips) written by Amir Taaki which in turn was derived from [Python's PEP-0001](https://peps.python.org/). In many places text was simply copied and modified. Although the PEP-0001 text was written by Barry Warsaw, Jeremy Hylton, and David Goodger, they are not responsible for its use in the Rollup Improvement Process, and should not be bothered with technical questions specific to Ethereum or the Rollups. Please direct all comments to the RIP editors. 597 | 598 | ## Copyright 599 | 600 | Copyright and related rights waived via [CC0](../LICENSE.md). 601 | -------------------------------------------------------------------------------- /RIPS/rip-7859.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7859 3 | title: Expose L1 origin information inside L2 execution environment 4 | description: Standardize the commitment of L1 origin data and historic L2 block hashes in L2 state 5 | author: Ian Norden (@i-norden), Bo Du (@notbdu), Christian Angelopoulos (@christianangelopoulos), Mark Tyneway (@tynes) 6 | discussions-to: https://ethereum-magicians.org/t/rip-7859-expose-l1-origin-information-inside-l2-execution-environment/22855 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2025-01-10 11 | requires: 12 | --- 13 | 14 | ## Abstract 15 | 16 | Pre-deployed smart contract for exposing inside the L2 execution environment information about the L1 blocks that the L2 17 | most recently included bridge inputs from. 18 | 19 | ## Motivation 20 | 21 | L2 blocks are composed of both L2 transactions sent directly to the sequencer and transactions that derive from 22 | deposit transactions to the native bridge on the L1. The inclusion of L1 deposit inputs into an L2 block creates 23 | a mapping between L2 blocks and the L1 blocks they are produced from. The latest L1 block to contribute to the state of 24 | an L2 block is called that L2 block's `L1_ORIGIN`. 25 | 26 | By including information about the `L1_ORIGIN` in the L2 execution environment and making it accessible to other 27 | contracts on the L2 we unlock the capability to verify arbitrary state claims about the L1. 28 | 29 | This capability is useful for a wide range of standards including verification in cross-L2 communication such as 30 | [RIP-7755](./rip-7755.md), enforcing L2 consistency checks such as [RIP-7789](https://ethereum-magicians.org/t/rip-7789-cross-rollup-contingent-transactions/21402), 31 | and verifying reads from the L1 such as [RIP-7728](./rip-7728.md) and [ERC-3668](https://eips.ethereum.org/EIPS/eip-3668). 32 | In general, it is useful to any contract on the L2 that needs to verify arbitrary L1 state, storage, transaction, or 33 | receipt data inside the L2. 34 | 35 | This extends to verifying claims about other L2s that settle their state into Ethereum, providing a simple mechanism 36 | for interoperability between L2s without additional trust assumptions. If these L2s also support an 37 | [EIP-2985](https://eips.ethereum.org/EIPS/eip-2935) ring buffer containing their historic block hashes then it becomes 38 | feasible to verify claims about their receipts and transactions even if the L2 only settles outputs sparsely. 39 | 40 | ## Specification 41 | 42 | This specification defines the contract interface for accessing information about the current and historic `L1_ORIGIN`s 43 | inside the L2 execution environment as well as defines the invariants that constrain the meaning of `L1_ORIGIN`. It also 44 | specifies a pre-deployed contract address that should be the same across rollups. 45 | 46 | The precise mechanism by which this information is loaded into the L2 during derivation is not specified nor is the 47 | underlying data structure or its layout in the contract. Specification at this level is avoided in order to better 48 | accommodate the architectural diversity present in rollup stacks, allowing them to implement this interface as best fit 49 | for their system. 50 | 51 | However, it is necessary to define some constraints on the definition of the `L1_ORIGIN` for a given L2 block so that 52 | the protocols and contracts that leverage this interface can operate under a set of common assumptions across 53 | different rollup stacks. 54 | 55 | ### L1 Origin invariants 56 | 57 | We will begin by defining some invariants on the meaning of `L1_ORIGIN` 58 | 59 | 1. Every L2 block has an `L1_ORIGIN`. 60 | 2. An `L1_ORIGIN` must be a canonical L1 block. 61 | 3. For an L2 block N with timestamp/height greater than L2 block M the `L1_ORIGIN` of N must have a height/timestamp 62 | greater than the L1 origin of M or share the same `L1_ORIGIN`. 63 | 4. If an L2 block includes transactions derived from L1 inputs the `L1_ORIGIN` for that L2 block must be the latest 64 | (highest height/timestamp) L1 block that contributed L1 inputs. 65 | 66 | Notice from the above rules that two L2 blocks can share the same `L1_ORIGIN` and, in fact, this is necessary for all 67 | rollups that have a shorter blocktime than the L1 blocktime. 68 | 69 | Notice from the above that it is not necessary that sequential `L1_ORIGIN`s are contiguous L1 blocks. That is, if an L2 70 | block N has L1 block M as its `L1_ORIGIN` then the `L1_ORIGIN` for L2 block N+1 does not have to be L1 block M or L1 71 | block M+1 but could be L1 block M+2, M+3, M+x, etc. This is in order to accommodate rollup stacks that do not maintain a 72 | strict mapping of every L2 blocks to an L1 block but instead only consider L1 blocks when they contain deposit 73 | transactions. 74 | 75 | An important property that arises out of the above invariants is that the `L1_ORIGIN` for a given L2 block represents 76 | the latest L1 block whose reorg would necessitate a reorg of that L2 block. 77 | 78 | ### Contract interface 79 | 80 | With these invariants in place we now define the contract interface for exposing information about the `L1_ORIGIN`. 81 | In defining this interface we also define _what_ information about the `L1_ORIGIN` must be exposed. We define 9 methods 82 | in total for the `L1OriginSource` interface. These methods provide access to current and historic `L1_ORIGIN` values that 83 | we believe are most useful: block hash, state root, receipt root, transaction root, and block height. 84 | 85 | ```solidity 86 | interface L1OriginSource { 87 | function getL1OriginBlockHash() external view returns (bytes32 blockHash); 88 | function getL1OriginParentBeaconRoot() external view returns (bytes32 blockHash); 89 | function getL1OriginStateRoot() external view returns (bytes32 stateRoot); 90 | function getL1OriginReceiptRoot() external view returns (bytes32 receiptRoot); 91 | function getL1OriginTransactionRoot() external view returns (bytes32 transactionRoot); 92 | function getL1OriginBlockHeight() external view returns (uint256 blockHeight); 93 | 94 | function getL1OriginBlockHashAt(uint256 height) external view returns (bytes32 blockHash); 95 | function getL1OriginParentBeaconRootAt(uint256 height) external view returns (bytes32 blockHash); 96 | function getL1OriginStateRootAt(uint256 height) external view returns (bytes32 stateRoot); 97 | function getL1OriginReceiptRootAt(uint256 height) external view returns (bytes32 receiptRoot); 98 | function getL1OriginTransactionRootAt(uint256 height) external view returns (bytes32 transactionRoot); 99 | } 100 | ``` 101 | 102 | For these latter methods providing historic data access we specify that the data be available for _at least_ the most 103 | recent 8192 L1 blocks. 104 | 105 | ### Pre-deployed contract address 106 | 107 | The contract exposing the interface defined above should exist at a common address across all rollups. This address is 108 | called the `L1_ORIGIN_CONTRACT_ADDRESS` and is set to (tdb). 109 | 110 | ## Rationale 111 | 112 | ### Access to individual fields vs block hash or beacon block root 113 | 114 | Individual header fields are exposed in order to improve UX and reduce gas costs relative to exposing only L1 block 115 | hashes or beacon block roots. Opening a block hash or beacon root to access individual fields within them would require 116 | providing the entire preimage or SSZ proof in calldata. The preimage for a block hash is 708 bytes while the SSZ proof 117 | for a Merkle tree with depth of 3 or greater is 160+ bytes. SSZ Merkle trees for beacon blocks on average have a depth 118 | of 7 or 8 levels. 119 | 120 | To retain the ability to verify other fields of the L1 execution header or beacon block we still expose the block hash 121 | and beacon block root. 122 | 123 | ### Access to historic L1 origin information 124 | 125 | In this RIP we propose an interface that allows for access not to only the current `L1_ORIGIN` information but also 126 | for the last 8190 `L1_ORIGIN`s. This provides a view of the latest 8191 `L1_ORIGIN`s, matching 127 | (and motivated by) the lengths of the ring buffers in EIP-4788 and EIP-2935. This number of L1 blocks represents one 128 | sync committee period (256 epochs, 8192 slots), assuming no slots are skipped. 129 | 130 | Access to historic `L1_ORIGIN` information is useful for applications that need to verify claims about historic 131 | transactions or receipts since transaction and receipt roots do not accumulate across blocks. It is also useful for 132 | verifying state and storage at accounts or slots that are overwritten across blocks. Furthermore, it is useful for 133 | checking that two blocks from two distinct rollups are built off the same branch of Ethereum history regardless of if 134 | they share the same current `L1_ORIGIN`. 135 | 136 | ### Enforcing correctness of `L1_ORIGIN` 137 | 138 | Correct `L1_ORIGIN` selection and storage in the contract underlying the `L1OriginSource` interface must be enforced at 139 | rollup settlement time according to the invariant rules. This is accomplished by these rules being part of the 140 | derivation and STF logic codified into the L2 output verification logic (e.g. fault proof program or SNARK circuit). 141 | 142 | ### Tradeoffs vs L1SLOAD with verification deferred to settlement time 143 | `L1_ORIGIN` info exposed in the EVM could be used to verify L1SLOAD calls but another way to verify L1SLOAD calls is by 144 | deferring verification to settlement time in a manner analogous to how the correctness of the `L1_ORIGIN` view is 145 | enforced at settlement time. This approach provides a tremendous gas cost saving as inclusion proofs or SNARKs do not 146 | need to be provided and evaluated inside the L2 EVM. 147 | 148 | If L1SLOAD is implemented with deferred verification then it provides a clear cost advantage versus using the `L1_ORIGIN` 149 | to read L1 storage data. Nonetheless, access to the `L1_ORIGIN` as described here exhibits some properties that 150 | `L1SLOAD` does not: 151 | 152 | 1. It can be used to verify claims about accounts, receipts/logs, and transactions. 153 | 2. It can be used to verify claims about historic L1 data. 154 | 3. It can be used to check whether two rollups are building off the same Ethereum fork and enforce this as a condition 155 | for executing cross-rollup transactions (RIP-7789). 156 | 4. L1SLOAD cannot operate if the L2 sequencer loses connectivity to the L1. 157 | 5. Exposing an explicit linkage between L2 and L1 blocks in the VM can make it simpler for rollups to keep track of 158 | when they need to rollback due to a reorg on the L1. 159 | 6. Exposing an explicit linkage between L2 and L1 blocks in the VM can make it simpler for external apps/entities 160 | (outside the L2 VM) to tell what the L1 origin is. 161 | 7. L1SLOAD includes in its rationale a request for rollups to support an `L1_ORIGIN` view in order to enforce consistency 162 | of the returned values. 163 | 164 | Taken together, we believe that it would be best to both support L1SLOAD and expose an `L1_ORIGIN` view inside the VM. 165 | 166 | ### Meaning in the context of an L3 167 | An L3 can be thought of as an L2 of an L2, in this context the `L1_ORIGIN` is instead an `L2_ORIGIN`. The same 168 | information about the `L2_ORIGIN` can be exposed inside the L3 execution environment and the invariant rules for the 169 | meaning of the `L2_ORIGIN` are the same as defined for the `L1_ORIGIN` here. 170 | 171 | Inside the L3 it is possible to access `L1_ORIGIN` info through the `L2_ORIGIN` view since it commits to the 172 | `L1_ORIGIN` inside the L2. This access will be specific to how the `L1_ORIGIN` data is represented in the L2's storage 173 | and will require providing MMPT proofs opening the `L2_ORIGIN` state root down to where the `L1_ORIGIN` information 174 | is stored. For this reason, it may be advantageous to support both an `L1_ORIGIN` and `L2_ORIGIN` contract interface 175 | inside an L3. 176 | 177 | ## Backwards Compatibility 178 | 179 | This RIP is backwards compatible as it is only adding a new pre-deployed contract to the EVM. 180 | 181 | ## Potential implementation approaches 182 | 183 | We avoid specifying a single implementation for this RIP but use this section to provide some examples 184 | for how it may be implemented. 185 | 186 | One approach would be to use ring buffer constructions as in EIP-4788 and EIP-2935 where these ring buffers store 187 | the `L1_ORIGIN` field values. These buffers can be updated with a system call or transaction at the top of the L2 block 188 | using the L1 context available to the sequencer as it processes deposits from the `L1_ORIGIN` into the nascent L2 block. 189 | 190 | Another approach would be to use a contract such as Optimism's L1Block contract that stores each L1 header fields in its 191 | own contract variable. This contract is the original inspiration for this RIP. In this approach the sequencer includes 192 | at the top of a nascent L2 block an L1 attributes transaction that calls the L1Block contract with information about the 193 | current `L1_ORIGIN`. 194 | 195 | ## Test Cases 196 | 197 | N/A 198 | 199 | ## Reference Implementation 200 | 201 | N/A 202 | 203 | ## Security Considerations 204 | 205 | N/A 206 | 207 | ## Copyright 208 | 209 | Copyright and related rights waived via [CC0](../LICENSE.md). 210 | -------------------------------------------------------------------------------- /RIPS/rip-7875.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7875 3 | title: Canonical ERC-7802 token bridge address 4 | description: Standardize the ERC-7802 token bridge address on rollups that support it natively 5 | author: Yoav Weiss (@yoavw), skeletor (@skeletor-spaceman) 6 | discussions-to: https://ethereum-magicians.org/t/rip-7876-canonical-erc-7802-token-bridge-address/22826 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2025-02-09 11 | --- 12 | 13 | ## Abstract 14 | 15 | This proposal sets a standard address for the ERC-7802 token bridge address trusted by ERC-20 tokens that support ERC-7802 Crosschain minting/burning 16 | 17 | ## Motivation 18 | 19 | ### Permisionless cross-ecosystem same-address ERC20s 20 | 21 | ERC-7802 is a minimal interface for crosschain minting/burning of ERC-20 tokens. The token is requires to trust a bridge address and allow it to call `crosschainMint`/`crosschainBurn`. The bridge address would typically be immutable and affect the token's address as determined by CREATE2. 22 | 23 | EIP-7587 reserved a range for standardized precompiles/predeploys used by rollups. The proposal makes use of this range to reserve the token bridge address. 24 | 25 | By standardizing the bridge address we gain two advantages: 26 | 1. Tokens can be deployed in a future-proof manner on every chain. If/when a rollup adds native ERC-7802 capability to their canonical bridge, existing immutable tokens can benefit from the improved interoperability even though they were deployed earlier. 27 | 1. Tokens can deploy to the same CREATE2 address if they wish. Having the same bridge address means they don't need to pass a different argument during deployment. 28 | 29 | 30 | ### Shared security across rollup clusters 31 | 32 | Standardizing `TOKEN_BRIDGE_ADDRESS` creates a simpler and more predictable cross-rollup experience: 33 | 34 | 1. One trusted address: Developers only need to work with one bridge address across rollups, making both on-chain and off-chain devx easier. 35 | 36 | 1. Future-proof deployments: Tokens can be deployed once and remain compatible as more rollups adopt the standard, without needing upgrades or redeployments. 37 | 38 | 1. Cross-chain composability: Tokens, deployable at the same CREATE2 address, work across rollups automatically, reducing custom bridge logic and deployment overhead. 39 | 40 | 41 | By keeping things simple, scalable, and standardized, this approach makes cross-rollup token interactions more efficient for both developers and users. 42 | 43 | ## Specification 44 | 45 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. 46 | 47 | As of `FORK_TIMESTAMP` in the integrated EVM chain, add precompiled/predeployed contract which acts as an ERC-7802 token bridge at address `TOKEN_BRIDGE_ADDRESS` in `0x1ff` (indicates 0x00000000000000000000000000000000000001ff). 48 | 49 | The implementation is outside the scope of this proposal but it MUST implement a secure ERC-7802 bridge in `TOKEN_BRIDGE_ADDRESS` or not have anything in that address. 50 | 51 | The rollup MAY implement a token bridge at another address in addition to `TOKEN_BRIDGE_ADDRESS` but MUST not deploy something other than a secure ERC-7802 bridge to `TOKEN_BRIDGE_ADDRESS`. 52 | 53 | ### Constants 54 | 55 | | Name | Value | 56 | |------------------------|----------------------------------------------| 57 | | TOKEN_BRIDGE_ADDRESS | `0x00000000000000000000000000000000000001ff` | 58 | 59 | ## Rationale 60 | 61 | The `TOKEN_BRIDGE_ADDRESS` is chosen as `0x1ff` because it is an available address for precompile RIPs as defined in EIP-7587. 62 | 63 | The implementation is deliberately out of scope because each rollup may choose different bridging methods, whether it's between L1 and L2, or across L2s within a cluster. 64 | 65 | Rollups do not trust each other unless such trust has been established explicitly. Therefore tokens can safely trust `TOKEN_BRIDGE_ADDRESS` within each rollup. 66 | 67 | ## Backwards Compatibility 68 | 69 | No backward compatibility issues because `TOKEN_BRIDGE_ADDRESS` is currently empty in all rollups and shall remain so until standardized by a RIP, as per EIP-7587. 70 | 71 | ## Security Considerations 72 | 73 | The only trust assumption introduced by this proposal is that `TOKEN_BRIDGE_ADDRESS` will not contain a malicious implementation of an ERC-7802 bridge. This is no different from the trust assumption introduced by any other precompile address, e.g. that the `ECRECOVER` precompile at address `0x01` will not be backdoored. 74 | 75 | No crosschain trust assumptions are made. Each rollup SHALL determine its trust model and decide whether it only trusts its own L1 canonical bridge or establishes trust relations with other rollups. Such trust relations should only be considered between rollups that share a trust model and can verify each other's soundness and finality. 76 | 77 | ## Copyright 78 | 79 | Copyright and related rights waived via [CC0](../LICENSE.md). 80 | -------------------------------------------------------------------------------- /RIPS/rip-7952.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7952 3 | title: Native Account Abstraction RPC methods 4 | 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 5 | author: Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn) 6 | discussions-to: 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2025-01-01 11 | requires: 7560 12 | --- 13 | 14 | ## Abstract 15 | 16 | With the introduction of Account Abstraction as it is defined by [RIP-7560](./rip-7560.md) 17 | a number of existing RPC APIs are not capable of providing the necessary functionality. 18 | The required behaviour changes are significant enough to require an introduction of completely new methods 19 | to the Ethereum L2 clients implementing Account Abstraction. 20 | 21 | ## Motivation 22 | 23 | The process of creating a transaction has been getting increasingly more complex and interactive process 24 | with the growing complexity of on-chain protocols. 25 | The introduction of Account Abstraction introduces a new dimension for this complexity. 26 | 27 | As the AA transactions are executed atomically but consist of multiple sequential frames, 28 | it is not possible to reliably prepare parts of the AA transaction individually. 29 | 30 | For example, when creating an AA transaction that also performs a deployment of a `sender` smart account, 31 | it is all but impossible to perform a gas estimation for the execution frame using the existing `eth_estimateGas` API. 32 | 33 | Instead, an API specifically designed with Account Abstraction in mind must be used. 34 | 35 | ## Specification 36 | 37 | This document defines the API that the RIP-7560 compatible Ethereum nodes provide to the Smart Wallet applications. 38 | 39 | ### eth_estimateGasAA 40 | 41 | Estimate the amount of gas needed per frame of an AA transaction. 42 | Performs a search for gas limit values required to make each of the frames of the RIP-7560 transaction execute 43 | successfully and without running out of gas. 44 | 45 | This method is an equivalent to the legacy Ethereum `eth_estimateGas` RPC API method. 46 | This method is also a native AA equivalent to the `eth_estimateUserOperationGas` method for 47 | [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) UserOperations as defined in 48 | [ERC-7769](https://eips.ethereum.org/EIPS/eip-7769). 49 | 50 | For validation frames, only valid calls to an appropriate `AA_ENTRY_POINT` callback, 51 | such as `acceptAccount`, `acceptPaymaster`, `sigFailAccount` and `sigFailPaymaster`, are considered a success. 52 | 53 | Note, that in order for `eth_esimateGasAA` to function, both the wallet and the paymaster must correctly 54 | implement signature checks as described in RIP-7560.\ 55 | Most notably, the fields `senderValidationData` and `paymasterData` usually contain signatures for the transaction 56 | and therefore cannot be known before the transaction preparation is complete.\ 57 | The recommended solution to this problem is for the wallet to provide **stub data** for these contracts, 58 | as described in the [Suggested Paymaster Flow](#suggested-paymaster-flow) section. 59 | 60 | Once a signature verification over the **stub data** fails, the validation code must not revert or finish execution, 61 | but instead proceed as usual until making a `sigFailAccount` or `sigFailPaymaster` call accordingly.\ 62 | 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. 63 | 64 | The `eth_esimateGasAA` API optionally accepts the `State Override Set` object to allow users to modify 65 | the state during the gas estimation. 66 | This field as well as its behavior is equivalent to the ones defined for the `eth_call` RPC method. 67 | 68 | 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. 69 | 70 | Parameters: 71 | 72 | 1. OBJECT - The RIP-7560 transaction object. 73 | The `validationGasLimit`, paymasterValidationGasLimit, `paymasterGasLimit` and `callGasLimit` fields are optional. 74 | 2. QUANTITY | TAG - integer block number, or the string "latest", "earliest", "pending", "safe" or "finalized" 75 | 3. OBJECT - `State Override Set` 76 | The `State Override Set` option allows you to change the state of a contract before executing the call. This means you 77 | can modify the values of variables stored in the contract, such as balances and approvals for that call without 78 | actually modifying the contract on the blockchain. 79 | This behavior is equivalent to the one defined for the `eth_call` RPC method. 80 | 81 | Example: 82 | ```json 83 | { 84 | "id": 1, 85 | "jsonrpc": "2.0", 86 | "method": "eth_estimateGasAA", 87 | "params": [ 88 | { 89 | "sender": "0x783Ca0bD27E42357D6Dbc87E9Cf9eb3a8D513843", 90 | "senderValidationData": "0xdeadbeef", 91 | "deployer": "0xD6E4aA932147A3FE5311dA1b67D9e73da06F9cEf", 92 | "deployerData": "0xdeadbeef", 93 | "paymaster": "0x8410373DF6E9b20765c9599c26d585B2cd0Ef628", 94 | "paymasterData": "0xdeadbeef", 95 | "executionData": "0xdeadbeef", 96 | "builderFee": "0x9184e72a000", 97 | "maxPriorityFeePerGas": "0x9184e72a000", 98 | "maxFeePerGas": "0x9184e72a000", 99 | "accessList": [], 100 | "authorizationList": [ 101 | { 102 | "chainId": "0x1", 103 | "nonce": "0x15", 104 | "yParity": "0x25", 105 | "r": "0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea", 106 | "s": "0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c" 107 | } 108 | ] 109 | }, 110 | "latest", 111 | { 112 | "0x1111111111111111111111111111111111111111": { 113 | "balance": "0x9184e72a000", 114 | "nonce": "0x1", 115 | "code": "0xdeadbeef", 116 | "state": { 117 | "0x0000000000000000000000000000000000000000000000000000000000000001": "0x1" 118 | }, 119 | "stateDiff": { 120 | "0x0000000000000000000000000000000000000000000000000000000000000001": "0x1" 121 | } 122 | } 123 | } 124 | ] 125 | } 126 | ``` 127 | Returns: 128 | 129 | | Name | Type | Comment | 130 | |-----------------------------|----------|------------------------------------------------------------| 131 | | validationGasLimit | QUANTITY | | 132 | | callGasLimit | QUANTITY | | 133 | | paymasterValidationGasLimit | QUANTITY | if `paymaster` is set, `null` otherwise | 134 | | paymasterPostOpGasLimit | QUANTITY | if `paymaster` is set, `0` if not needed, `null` otherwise | 135 | 136 | Example: 137 | 138 | ```json 139 | { 140 | "validationGasLimit": "0x9184e72a000", 141 | "paymasterValidationGasLimit":"0x9184e72a000", 142 | "paymasterPostOpGasLimit":"0x9184e72a000", 143 | "callGasLimit": "0x9184e72a000" 144 | } 145 | ``` 146 | 147 | ### eth_callAA 148 | 149 | Execute the AA transaction in memory without broadcasting it to the mempool or committing it to the blockchain. 150 | An equivalent to the legacy Ethereum `eth_call` RPC API method. 151 | 152 | Inputs are equivalent to the ones defined for the [eth_estimateGasAA](#eth_estimategasaa) method. 153 | 154 | User can also provide the gas limit for all or some of the AA transaction frames.\ 155 | If gas limits are not provided, the RPC node provider is free to choose a default value.\ 156 | The RPC node provider should also choose a maximum acceptable gas limit value taking into consideration the 157 | block gas limit and other rules of the underlying L2 protocol. 158 | 159 | Does not require the transaction to be properly signed, meaning it continues execution after either an account 160 | or a paymaster contract make a `sigFailAccount` or `sigFailPaymaster` call. 161 | 162 | Returns the data that is returned by the top-level execution frame, gas usage info, 163 | as well as the full array of event logs emitted during the execution of the RIP-7560 transaction 164 | 165 | If any of the validation or execution frames reverts, returns an error object containing the revert message. 166 | 167 | Inputs: 168 | 169 | 1. OBJECT - The RIP-7560 transaction object. 170 | The `senderValidationData` field is optional. 171 | 2. QUANTITY | TAG - integer block number, or the string "latest", "earliest", "pending", "safe" or "finalized" 172 | 173 | Returns: 174 | 175 | - **returnData** - DATA - the return value of the `sender` execution frame 176 | - **gasUsed** - QUANTITY - the total amount of gas used by the transaction 177 | - **sigFailAccount** - QUANTITY - whether account called "sigFailAccount" or not 178 | - **sigFailPaymaster** - QUANTITY - whether paymaster called "sigFailPaymaster" or not 179 | - **status** - QUANTITY - whether the execution phase including the `paymasterPostOp` completed successfully 180 | - **logs** - ARRAY - an array of the event logs emitted during the transaction 181 | 182 | Example: 183 | ```json 184 | { 185 | "returnData": "0xdeadbeef", 186 | "gasUsed": "0x1a14b", 187 | "status": "0x1", 188 | "sigFailAccount": "0x1", 189 | "sigFailPaymaster": "0x1", 190 | "logs": [ 191 | { 192 | "transactionHash": "0x8fc90a6c3ee3001cdcbbb685b4fbe67b1fa2bec575b15b0395fea5540d0901ae", 193 | "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", 194 | "blockHash": "0x58a945e1558810523df00490ff28cbe111b37851c44679ce5be1eeaebb4b4907", 195 | "blockNumber": "0xeb8822", 196 | "data": "0x000000000000000000000000000000000000000000000000000000001debea42", 197 | "logIndex": "0x6c", 198 | "removed": false, 199 | "topics": [ 200 | "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", 201 | "0x0000000000000000000000005067c042e35881843f2b31dfc2db1f4f272ef48c", 202 | "0x0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585" 203 | ], 204 | "transactionIndex": "0x4e" 205 | } 206 | ] 207 | } 208 | ``` 209 | 210 | ### Suggested wallet flow 211 | The wallet should expose `wallet_prepareTransactionAA` or an equivalent API, to be called by dApps communicating with the wallet. 212 | 213 | The `wallet_prepareTransactionAA` API is meant to be implemented by the wallet application, 214 | and not the L2 client RPC node provider. 215 | 216 | The method accepts a partially filled RIP-7560 transaction object and fills in all the missing fields.\ 217 | These may include gas prices, gas limits, nonces etc.\ 218 | All parameters are optional. If the parameter is provided with a value, calling this method will never override it. 219 | 220 | The method returns the full transaction object that can be serialized and sent to the `eth_sendRawTransaction` API. 221 | 222 | In case the wallet was not able to fill the transaction object for any reason, 223 | the `wallet_prepareTransactionAA` method returns an appropriate error code. 224 | 225 | ### Suggested paymaster flow 226 | 227 | The Paymaster service should expose the `pm_getPaymasterStubData` and `pm_getPaymasterData` APIs as defined by the 228 | [ERC-7677](https://eips.ethereum.org/EIPS/eip-7677). 229 | 230 | The API defined there should be implemented by a third party paymaster service, 231 | and not by the L2 client RPC node provider. 232 | 233 | This API is expected to be used internally by the wallet application as part of the `wallet_prepareTransactionAA` flow. 234 | 235 | ### Add Account Abstraction support for all transaction-level RPC APIs 236 | 237 | This includes the following APIs: 238 | `eth_sendTransaction`, 239 | `eth_sendRawTransaction`, 240 | `eth_getTransactionByHash`, 241 | `eth_getTransactionReceipt`, 242 | `eth_getTransactionByBlockHashAndIndex`, 243 | `eth_getTransactionByBlockNumberAndIndex`. 244 | 245 | These methods have a very similar purpose and should support returning the new transaction type object. 246 | 247 | Note that the "transaction index position" is determined by the position of the transaction's **validation frame**. 248 | 249 | ### Errors 250 | 251 | Error format: 252 | 253 | - DATA - The revert data of the first reverted frame. 254 | - CODE - The error code indicating the type of error, which may include the entity that caused the revert on-chain. 255 | - MESSAGE - The human-readable error that may include a decoding of the `DATA` field if possible. 256 | 257 | Error codes: 258 | 259 | * code: -32500 - transaction validation failed by `sender`. 260 | The message field SHOULD be set to the revert message and data from the `sender`. 261 | 262 | * code: -32501 - transaction validation failed by `paymaster`. 263 | The message field SHOULD be set to the revert message and data from the `paymaster`. 264 | 265 | * code: -32502 - transaction validation failed by `deployer` 266 | The message field SHOULD be set to the revert message and data from the `deployer`. 267 | 268 | * code: -32503 - Transaction out of time range. 269 | The message field SHOULD include the requested time range and the current block timestamp. 270 | 271 | 272 | ## Rationale 273 | 274 | ### New methods instead of modification for existing ones 275 | 276 | While the `eth_esimateGasAA` and `eth_callAA` methods are simply RIP-7560 extensions of the existing 277 | `eth_esimateGas` and `eth_call` methods accordingly, 278 | the type of the return values for the existing methods does not match the needs of the Native Account Abstraction API. 279 | 280 | The approach of creating a new set of methods is cleaner in the long term as these methods may be used later in the 281 | EOF-based Native Account Abstraction as described in [EIP-7701](https://eips.ethereum.org/EIPS/eip-7701). 282 | 283 | ### The `eth_callAA` returned data format 284 | 285 | The legacy `eth_call` method returns a single DATA array representing the return data of the single top-level 286 | call frame of a legacy transaction. 287 | 288 | However, this approach would not be sufficiently useful for the Native Account Abstraction solution.\ 289 | The top-level frame of the execution phase is a call to the `sender` smart account that may consist of multiple 290 | inner batched calls. 291 | 292 | Furthermore, the code in the `sender` address is frequently just 293 | a proxy contract that does not propagate the implementation's returned data. 294 | 295 | In order to allow smart contract wallets to reliably expose any data to the off-chain execution we have little choice 296 | but to rely on the existing mechanism of emitting the event logs. 297 | 298 | ## Backwards Compatibility 299 | 300 | The added methods are not interfering with any existing code and should pose no backwards compatibility issues. 301 | 302 | ## Security Considerations 303 | 304 | ### Estimate Gas flow in smart contracts 305 | 306 | As mentioned in the [eth_estimateGasAA](#eth_estimategasaa) section, the `sender` and `paymaster` smart contracts 307 | are expected to explicitly implement a special code flow to support the gas estimation. 308 | 309 | This code is supposed to only be executable during the `eth_estimateGasAA` and MUST never result in a valid transaction. 310 | In case this constraint is violated the contract will be vulnerable to various potential threats. 311 | 312 | ## Copyright 313 | 314 | Copyright and related rights waived via [CC0](../LICENSE.md). 315 | -------------------------------------------------------------------------------- /RIPS/rip-7953.md: -------------------------------------------------------------------------------- 1 | --- 2 | rip: 7953 3 | title: System Events for Native Account Abstraction 4 | description: Events emitted automatically for Native Account Abstraction transactions to simplify transaction data access 5 | author: Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn) 6 | discussions-to: 7 | status: Draft 8 | type: Standards Track 9 | category: Core 10 | created: 2025-04-01 11 | requires: 7560 12 | --- 13 | 14 | ## Abstract 15 | 16 | This proposal describes how system events injected by the virtual machine directly without calls to the `LOG` opcodes 17 | while executing the RIP-7560 transactions 18 | 19 | ## Motivation 20 | 21 | The [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) defines an `EntryPoint` contract that accepts 22 | an array structs named `UserOperation` and executes them as a part of an Account Abstraction protocol. 23 | 24 | The `EntryPoint` contract emits events during the execution of a `UserOperation` in order to expose 25 | some of the details of the on-chain state that would not be available otherwise. 26 | 27 | Additionally, the API for Ethereum events provides support for unique and useful features, 28 | such as event subscriptions or indexed parameters. 29 | 30 | A set of similar proposals exists for the Ethereum L1 as well, 31 | notably [EIP-7708](https://eips.ethereum.org/EIPS/eip-7708) and [EIP-7889](https://eips.ethereum.org/EIPS/eip-7889). 32 | 33 | ## Specification 34 | 35 | ### System Transaction Events 36 | 37 | We define the following system-level events that are emitted as part of an RIP-7560 transaction: 38 | 39 | ```solidity 40 | event RIP7560TransactionEvent( 41 | address indexed sender, 42 | address indexed paymaster, 43 | address indexed deployer, 44 | uint256 nonce, 45 | uint256 executionStatus 46 | ); 47 | 48 | event RIP7560TransactionRevertReason( 49 | address indexed sender, 50 | uint256 nonce, 51 | bytes revertReason 52 | ); 53 | 54 | event RIP7560TransactionPostOpRevertReason( 55 | address indexed sender, 56 | address indexed paymaster, 57 | uint256 nonce, 58 | bytes revertReason 59 | ); 60 | ``` 61 | 62 | * `RIP7560TransactionEvent` event is emitted in the end of each RIP-7560 transaction. 63 | 64 | * `RIP7560TransactionRevertReason` event is emitted if the RIP-7560 transaction's execution frame 65 | has reverted with a non-zero length return data. 66 | 67 | * `RIP7560TransactionPostOpRevertReason` event is emitted if the RIP-7560 transaction Paymaster's "postOp" call 68 | has reverted with a non-zero length return data. 69 | 70 | The bytes array returned as the `revertReason` parameter is truncated to its maximum length of `MAX_REVERT_REASON_SIZE`. 71 | Any data returned above that length will not be observable in a transaction receipt. 72 | 73 | The gas cost of System Transaction Events is not charged separately and is covered by the `AA_BASE_GAS_COST` 74 | of a transaction. 75 | 76 | The values for the `executionStatus` are the following: 77 | 78 | * `success` = 0 79 | * `executionFailure` = 1 80 | * `postOpFailure` = 2 81 | * `executionAndPostOpFailure` = 3 82 | 83 | All events are emitted at the `AA_ENTRY_POINT` address. 84 | 85 | ## Rationale 86 | 87 | ### Not using transaction receipt 88 | 89 | Some of the data exposed as part of the system events can be exposed as part of the transaction receipt as well. 90 | 91 | There are a few reasons to expose this data as a system event: 92 | 93 | * Backwards-compatibility with ERC-4337 for existing Account Abstraction tooling. 94 | 95 | As the entire technological stack that exists around Account Abstraction so far has evolved around the 96 | ERC-4337 protocol, abandoning event-based approach may make some existing tools infeasible. 97 | This loss in functionality is unnecessary and is easily avoidable. 98 | 99 | * Events provide search, filtering and subscription API that does not exist for the Transaction Receipts. 100 | 101 | For example, with system events we are able to search for all transactions using a certain `Account` or `Paymaster`. 102 | This functionality may be crucial for any reputation-based systems like ERC-7562 mempools. 103 | 104 | * Modifications to Transaction Receipts may pose more challenges than to emitted events. 105 | 106 | As the fields of Account Abstraction continues to evolve, it is possible there will be additional RIPs 107 | defining additional system events in the future. 108 | It is also possible that system events will be adopted by L2s for tasks other than Account Abstraction. 109 | If each of these proposals needed to introduce a modification to the Transaction Receipt schema, 110 | it would result in an unmanageable complexity. 111 | 112 | ## Backwards Compatibility 113 | 114 | This proposal is meant to introduce a certain form of backwards compatibility between RIP-7560 and ERC-4337. 115 | 116 | However, the event signatures are not equivalent and users will have to explicitly add support for these system events. 117 | 118 | ## Security Considerations 119 | 120 | As system events are created by the execution environment directly, 121 | there is no added risk in accepting the data exposed by these events. 122 | 123 | ## Copyright 124 | 125 | Copyright and related rights waived via [CC0](../LICENSE.md). 126 | -------------------------------------------------------------------------------- /assets/rip-7212/benchstat_compare_test: -------------------------------------------------------------------------------- 1 | goos: darwin 2 | goarch: arm64 3 | pkg: github.com/ethereum/go-ethereum/core/vm 4 | │ compare_p256Verify │ compare_ecrecover │ 5 | │ sec/op │ sec/op vs base │ 6 | PrecompiledP256Verify/p256Verify-Gas=3450-8 57.75µ ± 1% 7 | PrecompiledEcrecover/-Gas=3000-8 50.48µ ± 1% 8 | geomean 57.75µ 50.48µ ? ¹ ² 9 | ¹ benchmark set differs from baseline; geomeans may not be comparable 10 | ² ratios must be >0 to compute geomean 11 | 12 | │ compare_p256Verify │ compare_ecrecover │ 13 | │ gas/op │ gas/op vs base │ 14 | PrecompiledP256Verify/p256Verify-Gas=3450-8 3.450k ± 0% 15 | PrecompiledEcrecover/-Gas=3000-8 3.000k ± 0% 16 | geomean 3.450k 3.000k ? ¹ ² 17 | ¹ benchmark set differs from baseline; geomeans may not be comparable 18 | ² ratios must be >0 to compute geomean 19 | 20 | │ compare_p256Verify │ compare_ecrecover │ 21 | │ mgas/s │ mgas/s vs base │ 22 | PrecompiledP256Verify/p256Verify-Gas=3450-8 59.73 ± 1% 23 | PrecompiledEcrecover/-Gas=3000-8 59.42 ± 1% 24 | geomean 59.73 59.42 ? ¹ ² 25 | ¹ benchmark set differs from baseline; geomeans may not be comparable 26 | ² ratios must be >0 to compute geomean 27 | 28 | │ compare_p256Verify │ compare_ecrecover │ 29 | │ B/op │ B/op vs base │ 30 | PrecompiledP256Verify/p256Verify-Gas=3450-8 1.523Ki ± 0% 31 | PrecompiledEcrecover/-Gas=3000-8 800.0 ± 0% 32 | geomean 1.523Ki 800.0 ? ¹ ² 33 | ¹ benchmark set differs from baseline; geomeans may not be comparable 34 | ² ratios must be >0 to compute geomean 35 | 36 | │ compare_p256Verify │ compare_ecrecover │ 37 | │ allocs/op │ allocs/op vs base │ 38 | PrecompiledP256Verify/p256Verify-Gas=3450-8 33.00 ± 0% 39 | PrecompiledEcrecover/-Gas=3000-8 7.000 ± 0% 40 | geomean 33.00 7.000 ? ¹ ² 41 | ¹ benchmark set differs from baseline; geomeans may not be comparable 42 | ² ratios must be >0 to compute geomean 43 | -------------------------------------------------------------------------------- /assets/rip-7212/ecrecover_benchmark_test: -------------------------------------------------------------------------------- 1 | goos: darwin 2 | goarch: arm64 3 | pkg: github.com/ethereum/go-ethereum/core/vm 4 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 23295 50034 ns/op 3000 gas/op 59.95 mgas/s 800 B/op 7 allocs/op 5 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 23734 50558 ns/op 3000 gas/op 59.33 mgas/s 800 B/op 7 allocs/op 6 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 23823 50586 ns/op 3000 gas/op 59.30 mgas/s 800 B/op 7 allocs/op 7 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 23913 50049 ns/op 3000 gas/op 59.94 mgas/s 800 B/op 7 allocs/op 8 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 23721 50299 ns/op 3000 gas/op 59.64 mgas/s 800 B/op 7 allocs/op 9 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 23760 51160 ns/op 3000 gas/op 58.63 mgas/s 800 B/op 7 allocs/op 10 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 23151 50818 ns/op 3000 gas/op 59.03 mgas/s 800 B/op 7 allocs/op 11 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 23744 53451 ns/op 3000 gas/op 56.12 mgas/s 800 B/op 7 allocs/op 12 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 22837 50315 ns/op 3000 gas/op 59.62 mgas/s 800 B/op 7 allocs/op 13 | BenchmarkPrecompiledEcrecover/-Gas=3000-8 23823 50401 ns/op 3000 gas/op 59.52 mgas/s 800 B/op 7 allocs/op 14 | PASS 15 | ok github.com/ethereum/go-ethereum/core/vm 17.687s 16 | -------------------------------------------------------------------------------- /assets/rip-7212/p256Verify_benchmark_test: -------------------------------------------------------------------------------- 1 | goos: darwin 2 | goarch: arm64 3 | pkg: github.com/ethereum/go-ethereum/core/vm 4 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 20770 57970 ns/op 3450 gas/op 59.51 mgas/s 1560 B/op 33 allocs/op 5 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 20899 57769 ns/op 3450 gas/op 59.71 mgas/s 1560 B/op 33 allocs/op 6 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 20780 57343 ns/op 3450 gas/op 60.16 mgas/s 1560 B/op 33 allocs/op 7 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 20870 57740 ns/op 3450 gas/op 59.74 mgas/s 1560 B/op 33 allocs/op 8 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 20911 57411 ns/op 3450 gas/op 60.09 mgas/s 1560 B/op 33 allocs/op 9 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 20874 58423 ns/op 3450 gas/op 59.04 mgas/s 1560 B/op 33 allocs/op 10 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 20736 57552 ns/op 3450 gas/op 59.94 mgas/s 1560 B/op 33 allocs/op 11 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 19700 58235 ns/op 3450 gas/op 59.24 mgas/s 1560 B/op 33 allocs/op 12 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 20814 57681 ns/op 3450 gas/op 59.80 mgas/s 1560 B/op 33 allocs/op 13 | BenchmarkPrecompiledP256Verify/p256Verify-Gas=3450-8 20736 58806 ns/op 3450 gas/op 58.66 mgas/s 1560 B/op 33 allocs/op 14 | PASS 15 | ok github.com/ethereum/go-ethereum/core/vm 18.491s 16 | -------------------------------------------------------------------------------- /assets/rip-7560/flow_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7560/flow_diagram.png -------------------------------------------------------------------------------- /assets/rip-7560/unused_gas_attack_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7560/unused_gas_attack_overview.png -------------------------------------------------------------------------------- /assets/rip-7560/zoom_into_transaction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7560/zoom_into_transaction.png -------------------------------------------------------------------------------- /assets/rip-7711/rip_7560_block_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7711/rip_7560_block_overview.png -------------------------------------------------------------------------------- /assets/rip-7711/rip_7711_block_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7711/rip_7711_block_overview.png -------------------------------------------------------------------------------- /assets/rip-7755/call_delivery_magicspend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7755/call_delivery_magicspend.png -------------------------------------------------------------------------------- /assets/rip-7755/call_delivery_precheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7755/call_delivery_precheck.png -------------------------------------------------------------------------------- /assets/rip-7755/call_delivery_userop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7755/call_delivery_userop.png -------------------------------------------------------------------------------- /assets/rip-7755/cancelled_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7755/cancelled_request.png -------------------------------------------------------------------------------- /assets/rip-7755/happy_case.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7755/happy_case.png -------------------------------------------------------------------------------- /assets/rip-7755/happy_case_precheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7755/happy_case_precheck.png -------------------------------------------------------------------------------- /assets/rip-7755/request_flow_finality_delay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7755/request_flow_finality_delay.png -------------------------------------------------------------------------------- /assets/rip-7755/state_root_sharing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7755/state_root_sharing.png -------------------------------------------------------------------------------- /assets/rip-7810/RIP_process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/RIPs/1f55794f65caa4c4bb2b8d9bda7d713b8c734157/assets/rip-7810/RIP_process.png --------------------------------------------------------------------------------