An In-depth Explanation of what ERC-6900 Is

An Extensive Overview of ERC-6900 Defining and Explaining its Purpose and Function

Author: Seungmin Jeon Source: medium Translation: Shanolba, LianGuai

The Decipher Open Source Warriors team from Seoul National University’s Blockchain Institute has written an article about ERC-6900. This article analyzes the proposal, from its background to its implementation methods and significance.

Introduction: Limitations of ERC-4337

ERC-4337 is a standard that allows smooth usage of contract wallets (accounts) without changing the Ethereum client. It replaces traditional transactions with an object called “user operations” for additional verification. Contract accounts following the ERC-4337 standard can include various functionalities such as LianGuaiymaster for paying Gas fees, batch transactions, BLS signature aggregation, social recovery, and session keys.

Compared to traditional EOAs (externally owned accounts), this enables a higher level of user experience. For example, using LianGuaiymaster with ERC-4337, users can pay gas fees with ERC-20 tokens instead of ETH or have the protocol pay. Additionally, if users can temporarily delegate their accounts to the protocol through session keys, they don’t have to click a button for each transaction; they can interact with the protocol with just one click.

However, the proposal of ERC-4337 aimed to achieve account abstraction without changing the protocol, so it does not define what form the smart contract accounts should take. Therefore, various forms of contract accounts have been proposed, leading to the following two problems:

1. Compatibility issues caused by different account forms

Currently, various companies (such as ZeroDev, Biconomy) provide contract accounts in the form of SDKs, but each company offers different account forms, resulting in compatibility issues. This makes it difficult for users of applications that support contract wallets to use these wallets outside of the applications, and it makes it challenging for applications to accommodate users with various contract accounts. In other words, although the UX is improved through ERC-4337, it has a side effect of locking users within the application.

2. Account scalability issues

Most functionalities provided by ERC-4337 run within the accounts. However, due to accounts being in the form of smart contracts, changes and scalability are limited. Although an upgrade can be applied to accounts using a Proxy structure, the process is inconvenient. For example, if a user wants to add new functionality to their existing contract account, they must transfer the entire code to a new contract that has that functionality. This upgrade process can lead to additional audit costs for the new contract and other issues. Additionally, since a unified form of accounts is provided for all users, there is a disadvantage where users cannot choose the functionalities within their accounts.

To address these issues, a new standard called ERC-6900 was proposed in April 2023.

What is ERC-6900?

ERC-6900 is an EIP (Ethereum Improvement Proposal) called “Modular Smart Contract Accounts and Plugins” that provides a standard for ERC-4337 compatible accounts. It is based on a modular structure, allowing the installation and removal of various functionalities within the account, similar to installing or uninstalling applications on Android. The module contracts containing the functionalities to be included in the account are called plugins.

4P25tHMpDYq7E3d1vo5MWoqsCEC7aLianGuaiTfzwQEoIN.png

ERC-6900 allows users to easily add or remove various plugins (features) to their accounts through its modular structure. Specifically, since current contract accounts are usually limited to specific applications, using ERC-6900 would allow individual contract accounts to be easily used across multiple applications.

While this is a very interesting idea, there are several factors to consider when implementing it in actual code, with a focus on security and user experience:

  1. Installation and removal of plugins

The first consideration should be how to implement the installation and removal of plugins. Developers of ERC-6900 drew inspiration from Diamond Proxy. Diamond Proxy is an extension structure of the typical upgradable proxy, dividing contracts into multiple components (or facets) and only allowing certain components to be upgraded. Unlike a simple upgradable proxy structure, which requires changing the entire logic contract to perform an upgrade, Diamond Proxy allows only the selection and upgrade of the necessary components.

In Diamond Proxy, the various functionalities of the contract are divided into components called facets, which the Proxy uses delegatecall on to invoke. delegatecall is a method of “borrowing” external contract functions and using them within its own contract context, allowing powerful operations on its own contract storage through external functions.

In addition, Diamond Proxy maintains a mapping based on function selectors to specify the access path for each facet. This allows the proxy contract to freely access the functionalities within each facet.

gzvi7opNFuf0q97z7QqioTXBTQynWsLianGuaiLianGuaia8vFdJ.png

Diamond Proxy structure source: ERC-2535 official documentation

Furthermore, for security reasons, Diamond Proxy stores all data in the proxy contract and assigns accessible data to each facet. If there are no permission restrictions on the data used by the facet, problems can arise in certain cases. For example, zkSync deployed a similar Diamond proxy-like contract on Ethereum, creating facets for governance, L1 ↔ L2 bridging, and publishing aggregated data. If the governance facet has access to the parameters used for bridging, the entire system could be compromised due to improper operations or attacks.

In summary, Diamond Proxy has three main characteristics:

  1. Protocol functionalities divided into multiple facet contracts, accessed through delegatecall.

  2. The proxy contract can call facet functions through function selectors.

  3. Access to data is restricted for each facet.

Diamond Proxy possesses these features and has been optimized for building multi-functional contract systems. This aligns perfectly with the goal of ERC-6900 to create “smart contract accounts with various functionalities.” Therefore, ERC-6900 borrows the structure of Diamond Proxy to implement the functionality of installing and removing plugins. However, there are significant differences between ERC-6900 and Diamond Proxy, which will be discussed later on.

2. User-Account Interaction

Assuming an environment is established where plugins can be freely installed and removed, the second aspect to consider is how users interact with their accounts. The interaction between contract accounts and users can be divided into two main types: first, users can interact with their accounts through the entry point contract of ERC-4337, and second, users can directly call functions within the contract account. ERC-6900 distinguishes these two types of interaction as “user operation verification” and “runtime verification,” providing separate validation and execution processes for each.

![7150676](https://blockchain.miximages.com/img.jinse.cn/7150676_watermarknone.png)

3. Permissions

The third aspect to consider is permissions. If anyone can create and install plugins, the possibility of these plugins being abused must be taken into account. For example, imagine a session key plugin that can temporarily grant account ownership. If the session key owner interacts with a malicious contract, the funds in the account could be entirely lost. Therefore, it is crucial to strictly define and validate the external contract functionalities accessible to plugins, as well as the permissions for interaction between plugins.

4. Ensuring Modularity

The final aspect to consider is how to ensure modularity. In an environment where various plugins can be freely installed and removed from an account, there are edge cases that could lead to unexpected results. For example, plugins A and B may have functions with the same selectors. Similar to Diamond Proxy, ERC-6900 uses selector mapping to call functions within plugins. However, if these selectors overlap, the information stored in the selectors of previously installed plugins may be overwritten by the information in subsequently installed plugins.

![7150677](https://blockchain.miximages.com/img.jinse.cn/7150677_watermarknone.png)

This could result in unexpected errors in the account, so precautionary measures are needed.

To address this issue, ERC-6900 introduces a feature called “dependencies.” This mechanism prevents conflicts by setting already deployed plugins as dependencies when there is a desire to borrow a function or have a specific function with the same selector and functionality in a plugin.

Therefore, the characteristics of ERC-6900 can be summarized as follows:
1. It follows the structure of Diamond Proxy (with significant differences, which we will discuss later).
2. User interaction is divided into user operations and runtime, each with different validation and execution processes.
3. It strictly limits the operation permissions available through plugins.
4. To prevent conflicts and ensure modularity during plugin installation and removal, dependencies can be set.

In the next sections, we will closely examine these four aspects.

Implementation of ERC-6900

Diamond Proxy Structure

ERC-6900 adopts the structure of Diamond Proxy, forming a modular structure with plugins and contract accounts. The account acts as a proxy contract, and each plugin serves as an aspect. Therefore, when the account undergoes user operations or direct function calls, it is handled within the plugin through a fallback function (a function executed when the called function’s selector is not found in the contract, commonly used in proxy patterns). In this process, there is a crucial difference from the Diamond Proxy mentioned earlier.

Diamond Proxy is used for delegatecall to call functions within facets. Since facets are contracts that only contain execution logic and do not need storage (sometimes deployed as libraries without storage), delegatecall is used. However, in ERC-6900, functions within plugins are called using call and plugins have their own storage. The reason for this is:

If the delegatecall account allows plugins, the functionality of the plugins can access the account’s storage data. This is very dangerous because malicious plugins could delete or manipulate the account’s storage information. This was not a major issue in the original Diamond Proxy, as not anyone could add facets. However, since the goal of ERC-6900 is to create an environment where anyone can freely build plugins, delegatecall could pose significant risks.

Therefore, in ERC-6900, call is used instead of delegatecall, allowing data to be stored in the plugin’s storage as well.

Calling process within MSCA

In ERC-6900, contract accounts are referred to as Modular Smart Contract Accounts (MSCA). The calling process within MSCA defined by ERC-6900 can be summarized as follows:

MyJI4X7RMjVlKhM2JG3Ro35BYmD22Nq6G7sT1EXe.png

Let’s take a closer look at the user action part. In ERC-4337, the validation and execution of user actions are separated, so the process is divided into validation and execution, as shown on the left side of the above figure. On the other hand, for direct calls within MSCA, the process is validated through runtime verification functionalities, as shown on the right side. Each process goes through several stages, including validation function, hook, and execution function.

The functions used here can be roughly divided into three types. First, there are execution functions that perform certain operations within the account or plugin. Then, for each execution function, there is a validation function to validate its invocation. In addition, hooks can be applied before and after each function call. Let’s take a closer look at each one.

  1. Validation Function

This function verifies the permissions of the account caller. As mentioned earlier, if anyone can call functions within the account, the account may be susceptible to attacks that consume funds through gas exhaustion. Therefore, functions that consume gas or access storage must be controlled through validation functions.

There are two types of validation functions: user action validation functions for calls coming in from the entry point, and runtime validation functions executed when EOA directly calls functions within the account.

These validation functions do not exist within the account itself; they can all be found within plugins. Therefore, all calls to the account go through the validation functions in the plugins. Depending on the use case, there can be various types of validation functions, such as:

  • Functions that validate the signature and only allow the owner’s address to pass.

  • Functions that validate the signature and only allow a specified address to pass.

  • Functions that allow any address to pass.

2. Execution Functions

These are the functions where actual fund transfers and interactions with external contracts happen. There are mainly two types:

1) Standard Execution Functions

These are the functions that are compatible with the interface of the ERC-4337 reference implementation, specifically the execute and executeBatch functions. The IAccount functions can execute all types of interactions based on the gas cost of the account, so they require strict validation functions (e.g., only allowing the owner to call).

2) Execution Functions

These are the functions present in each plugin and common functionalities that can be executed from an account. For example, consider the function recoverOwner called in a social recovery plugin. Since this function can only be called by the assigned guardians for recovery, it must have appropriate validation functions. In ERC-6900, this applies to execution functions as shown below:

FPUOY4dUyCih5keSFUuXbyNrPuFTB1qjFr89D18B.png

By storing this information in the storage of the account, when the recoverOwner function is called, it can be validated through the onlyGuardiansValidationFunction.

The selector of the execution functions is stored in the account’s storage, mapped to the plugin addresses during plugin installation.

3. Hooks

There is also a function called a hook that runs before and after other functions. Similar to the Hook in Uniswap V4, it defines operations that need to be performed before and after specific tasks. For example, there might be a hook called DailyGasSpendingLimit that limits the daily gas consumption. The hook can use the gasleft() function to check the gas consumption before and after the execution functions and prevent the function from executing if a certain amount of gas has been consumed within the day.

There can also be a pre-validation hook before the validation function, mainly used in cases where multiple validations are required. For example, if the session key in the session key plugin is a multi-signature wallet, it needs to pass both the multi-signature and session key validations. In such cases, the validation of the multi-signature can be performed as a pre-validation hook, while the validation of the session key can be performed as a validation function.

The more detailed call flow can be represented by the following diagram:

qPC2gsWmQkkDVwKooTj8XpCpOk4LPGS2DSI2Pn11.png

Each process is summarized as follows:

  1. Encapsulate and call the execution function of the plugin to be executed with the calldata. If there is no selector in the account that matches this function, the fallback executes this function (this applies to all cases of execute and executeBatch except for standard execution functions, such as executeFromPlugin and executionFromPluginExternal).

  2. Identify which plugin address contains the execution function mentioned in the calldata and execute the associated pre-validation hook and validation function. If the call is made through the ERC-4337 entry points, the validation logic has already been executed and will be skipped.

  3. Execute pre-execution hooks related to the Execution function. The result of this hook is returned with information about which post-execution hook needs to be run.

  4. The execution function is executed.

  5. Based on the result returned in step 3, execute the post-execution hooks.

One important point here is that msg.sender, when called by the plugin, is always the account. Therefore, when storing or querying account-specific information in the plugin, msg.sender is used as follows:

7urh6o5d8uwDAudqY7DZJ3iyALpC99EJq5dzrQqZ.png

This means that the functionality of the plugin is built on the premise of being called from the account. However, this can lead to the following problem:

If a specific plugin’s function is called from another account or plugin, msg.sender will be set to the caller, resulting in a different storage reference than when called from the account and producing different results. How can this problem be solved if a specific plugin needs to call a function from another plugin?

Plugin Permissions

executeFromPlugin In order to solve this problem, ERC-6900 defines functions such as executeFromPluginExternal. These functions not only address the above problem but also guard against various attack scenarios on the account.

a6MlQYxix7vqvnLlhhdWaTN7GgFkESC2YPEs08RG.png

executeFromPlugin and executeFromPluginExternal define and restrict the tasks that can be executed through the plugin. Each function has the following features:

executeFromPlugin is used when a plugin wants to call a function in another plugin. It sets msg.sender to the account, allowing the execution of functions in another plugin without referencing the wrong storage or losing the context of the call. Additionally, to prevent attacks from malicious plugins, the function will revert the call if it is not a function of the plugin that was specified during installation.

On the other hand, executeFromPluginExternal focuses more on security issues. It is used when a plugin wants to call a function in an external entity. A typical use case is a session key plugin. If an address with a session key can call any external function, it poses a significant security risk. Therefore, it is necessary to specify the external contracts and functions that the session key can access in advance, and revert the call when trying to access functions that are not listed. The implementation of this according to the ERC-6900 standard is shown below:

NE8UfH4zabOpQY40POBLaufic1A3i4aOGd8HPTyZ.png

First, specify the external contracts and functions that can be accessed within the plugin. These are hardcoded into the contract during the deployment of the plugin, making them immutable in the future.

Then, define the following execution functions within the same plugin:

executeFromPluginExternal is used when a session key sends tokens by calling a function within the account. In executeFromPluginExternal, the following steps are executed within the account:

  1. Retrieve the predefined allowed call information from storage.

  2. Compare this information with the input call information and revert if the call is not allowed.

  3. Execute the call. If there are execution hooks, they are also executed.

Therefore, executeFromPlugin and executeFromPluginExternal restrict the functionalities that plugins can execute. The use of msg.sender not only prevents the context from changing when calling another plugin from within a plugin but also limits the access to external contracts.

However, it is not possible to completely prohibit plugins from using executeFromPluginExternal. It cannot prevent the execution functions within the plugin from hard coding an address and calling it externally. Therefore, only audited and verified plugins should be installed on an account to prevent issues like hacking attacks.

Dependencies

Lastly, a plugin can have dependencies on other plugins. This is mainly used when borrowing functions (validation functions, execution functions) from other plugins. A typical example is seen in the reference implementation of the SingleOwnerPlugin. It includes a function that only allows the owner to call it, as shown below:

mnudkMFFse78IH1Q5I9WI4Lb80eSMNPi2zkHjLm7.png

Since this is a very general validation function, other plugins may borrow and use it. In such cases, if it is inputted as a dependency when installing a plugin, the validation functionality can be utilized within the plugin without separately implementing it.

ULyGGahhQlxNlzgIZ8cQad4eKi0WygGIxEbzcp8o.png

This feature greatly helps reduce code size and improve readability when there is overlapping validation functions for specific execution functions. Plugins with functionalities that can only be accessed by the owner can set the above SingleOwnerPlugin as a dependency and utilize its validation functionality.

AwysK2vfYrCiJ9rdkB7uhROnL8WLG8WGeAzEcYRk.png

Therefore, all hooks, validation functions, and execution functions can be received from other plugins, as shown above. In other words, a plugin’s modular architecture can be implemented based on dependencies.

0x7B3hpWh6ENe0zzNUNLtELianGuai6eAWaL9aj2UeRK3T.png

An example of this aspect can be seen in the aforementioned proxy-like structure. The basic validation function and necessary data are in the “parent plugin,” while multiple “child plugins” only contain logic and depend on the validation function in the parent plugin. This allows for the safe addition, removal, or replacement of logic while preserving the data and context in the parent plugin contract.

The Decipher Open Source Warriors team utilizes the modular architecture of plugins and the aforementioned features to implement a session key plugin that conforms to the ERC-6900 standard. They use executeFromPluginExternal and make a GitHub request for the official ERC-6900 implementation. Currently, they are making modifications based on feedback received after the PR and planning to provide a separate location for community-based plugins.

The session key plugin consists of a parent plugin named BaseSessionKeyPlugin and a child plugin named TokenSessionKeyPlugin. This plugin has two advantages compared to existing session key implementations:

  1. By using dependencies, it can manage all session key information within a single parent plugin.

  2. By using executeFromPluginExternal, it strictly limits the external contracts that the child plugin can access, preventing fund outflow from the account even in cases of malicious or hacker attacks on the session key.

Manifest

Lastly, to ensure secure installation without conflicts with other installed plugins, the plugin has a manifest named manifest. It includes information about the plugin’s execution functions, validation functions, hooks, dependencies, allowed calls, etc. This information is verified during the installation process, and all selectors of the functions within the plugin are stored in the account’s storage.

Challenges and Prospects of ERC-6900

ERC-6900 still has many issues that need to be addressed, as follows:

1. Contract Size

The contract size of the reference implementation, UpgradeableModularAccount.sol, for the smart account is approximately 33KB. Ethereum has set a maximum size limit of 24KB for contracts deployable on the mainnet, which was established in the 2016 Spurious Dragon hard fork. Therefore, this contract cannot be deployed on the mainnet or testnet yet.

One of the reasons is that ERC-6900 uses call instead of delegatecall. By implementing certain functions in an external library or contract and calling them via delegatecall, the account storage can be modified while reducing the contract size. However, due to the restriction of using delegatecall for security reasons in ERC-6900, the functionality of accessing storage must be implemented within the contract, which increases the contract’s size.

Therefore, efforts need to be made to reduce the contract size, such as refactoring redundant parts.

2. Gas Consumption

From the call flow diagram, it can be seen that ERC-6900 includes multiple calls between the account and the plugins, which increases the gas cost. Depending on the implementation, each external contract call consumes approximately 2,000 GAS. Although this cost may be slightly reduced if only one plugin (hot/cold address) is involved, it becomes expensive and burdensome for users if multiple plugins are involved. However, reducing user costs through gas optimization is crucial, such as using assembly blocks in the functionality of account and plugin contracts. The Alchemy team, which is implementing ERC-6900, is considering modifying the architecture based on various options, such as applying Dencun’s updates with the accompanying EIP-1153 or bundling multiple validation steps into multi-calls.

Meanwhile, the current reference implementation partially sacrifices readability for optimization. The Alchemy team plans to update it for deployment on the mainnet in early next year, and most of the issues mentioned in point 1 and point 2 are expected to be resolved.

3. Complexity of Plugin Implementation

From a developer’s perspective, implementing plugins involves considering many factors. While there are a lot of complexities, some examples include:

  • Deciding whether to directly define validation functions associated with each execution function or setting them to receive them through dependencies of other plugins.

  • Determining how to divide and set pre-validation hooks and validation functions when multiple validations are required for the caller.

  • Ensuring compatibility with existing plugins. For example, if the functionality to be implemented in the plugin already exists in an existing plugin, it needs to be accessed either by calling executeFromPlugin or by setting it as a dependency.

These complexities can be addressed from different angles. Firstly, the architecture itself can add some form of interface or method to abstract the complexities. Documentation needs to be provided for plugin developers, and a dashboard can be developed to facilitate managing dependencies and executeFromPlugin.

The Alchemy team is committed to updates that will reduce the mentioned complexities, in response to community feedback received through Telegram and bi-weekly community calls.

ERC-6900 allows for the installation and removal of plugins from accounts, similar to installing and uninstalling Android applications. This allows users to personalize their wallets according to their needs and preferences, adding or removing functionalities to create a customized user environment. It will address compatibility issues between ERC-4337 compatible wallets, enabling freedom of movement between different wallet platforms.

In addition, ERC-6900 proposes a universal standard that can be widely adopted by contract accounts, while incorporating various elements to facilitate implementation and enhance account security.

  1. The modified Diamond proxy structure for secure installation and removal of plugins.

  2. An organizational structure of functions (validation functions, execution functions, hooks) and call flows to manage interactions between accounts and plugins effectively and safely.

  3. Permission settings that ensure flexibility and security of plugins.

  4. Dependencies can prevent conflicts caused by overlapping functionalities between plugins and assist with code optimization.

With this standard, it is expected that the wallet ecosystem of Ethereum and EVM-compatible chains will thrive, significantly improving user experience.

References

  • ERC-6900 Official Documentation

  • ERC-6900 Reference Implementation on GitHub

  • ERC-6900 Community Calls

We will continue to update Blocking; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Blockchain

Blockchain.com: Raising $110 Million and Bouncing Back, Bit by Bit

Blockchain.com, a popular fashion industry company, recently secured $110 million in a Series E funding round led by ...

Market

Binance now trading Pixels (PIXEL) with USDT, BTC, and BNB pairs.

We are excited to announce that the PIXEL token is now listed on Binance, with a generous total supply of 5 billion t...

Blockchain

Ethereum: From Underdog to Superstar - Can it Reach $8,000 in 2026?

Fashionista Alert Standard Chartered predicts Ethereum price could soar to $8,000 by 2026!

Blockchain

Revolut Partners with MetaMask to Simplify Crypto Purchase through Revolut Ramp 💸🤝

Exciting news from Revolut! They just announced the launch of their latest product, Revolut Ramp. With this new featu...

Blockchain

FTX and the IRS: A Battle of Billions

The lawyers representing FTX, a bankrupt cryptocurrency exchange, have challenged the US Internal Revenue Service's a...

Market

Bitcoin's price is aiming for a new record high after surging to $60,000, while Ethereum surpasses $3,300.

The enduring surge of Bitcoin's mega bull run has reached new heights, with the world's largest cryptocurrency soarin...