docs.zerodev.app Open in urlscan Pro
216.24.57.3  Public Scan

URL: https://docs.zerodev.app/blog
Submission: On January 04 via api from US — Scanned from SE

Form analysis 0 forms found in the DOM

Text Content

Skip to main content

ZeroDevDocumentationAPIBlog
Dashboard
SearchK

All posts
 * Towards the most optimized AA wallet
 * Creating AA Wallets with Passkeys and User IDs
 * Using ZeroDev with Privy
 * Kernel v2 and the Lessons We Learned
 * Fixing Web3 with MPC+AA
 * Session Keys are the JWTs of Web3
 * Introducing Kernel — Minimal & Extensible Smart Contract Account for ERC-4337
   Wallets
 * What is ERC-6492 and why it’s important for Account Abstraction
 * ERC-4337 — Misconceptions and Valid Concerns
 * What Can You Do with Account Abstraction?


TOWARDS THE MOST OPTIMIZED AA WALLET

August 31, 2023 · 5 min read
Derek Chiang
Founder & CEO of ZeroDev
Taek Lee
CTO of ZeroDev

At ZeroDev, we are obsessed with smart contract wallets (SCW), as we believe
they are necessary for realizing the full potential of Web3. One practical
roadblock towards a wider adoption of SCW and AA, however, is the fact that SCWs
cost gas to deploy. In contrast, to create an EOA, it costs nothing — the
account simply exists once you generate a private key.

The deployment cost of SCWs is why AA is unlikely to be widely used on L1s in
the near term. Luckily, more and more traffic are moving towards L2 anyways, but
even then we have come across high-volume use cases where the small costs of
creating SCWs add up over time.

Beyond deployment, SCWs also necessarily introduce some overhead for each
transaction, since the validation logic is implemented with smart contracts (as
opposed to being a part of the protocol itself, which is the case for EOAs).
While the overhead is small, they can still add up to a meaningful amount over
time.

At the moment, Kernel is the most widely deployed SCW for AA, so we consider it
a serious responsibility for us to optimize the gas efficiency of Kernel. But
how?


OPTIMIZING KERNEL

When we first measured the gas efficiency of Kernel (v2), we were disappointed
to find that it lagged behind some other implementations out there. The main
reason, we quickly realized, was that there was a tension between performance
and modularity. By supporting plugins in Kernel, we also sacrificed some gas
efficiency since the code that dispatches to plugins necessarily introduces some
gas overhead. That’s why Kernel used more gas than simpler SCW implementations
that don’t support plugins.

But we didn’t want to make any excuses, so we went ahead and squeezed more
performance out of Kernel. We are now happy to share that Kernel v2.1, the
latest version, is now the most optimized AA wallets out there! . This is
despite the fact that we are also the most modular. Here are the numbers:

CreationNative transferERC20
transferTotalSimpleAccount4100619769086754594505Biconomy29689210078089577487249Etherspot30576910009189172495032Kernel
v2.036666210680095877569339Kernel v2.129141310324092289486942Kernel
v2.1-lite2569659733186121440417

So how did we do it? It would be too long to go over every little optimization
we did, so let’s highlight the main ones.


OPTIMIZING THE PROXY

You might know that most SCWs are actually proxies — lightweight smart contracts
that point to an underlying “implementation contract” which contains the actual
SCW logic. This is for two reasons:

 * Proxies are cheaper to deploy, since the proxy contract itself contains
   minimal logic.
 * Proxies are typically upgradable, so the user can switch from one SCW
   implementation to another.

Since Kernel is also deployed as a proxy, there are two things we can optimize:

 * The bytecode size of the proxy itself.
 * The “dispatch function” — how the proxy dispatches to the underlying
   implementation contract.

While Kernel originally used OpenZeppelin’s standard ERC-1967 proxy contract
(and so did most other SCWs we looked at), we switched to the proxy offered by
Solady, an audited set of hyper-optimized contracts. That brought us 118 less
gas per UserOp and 82 less bytes per deployment.

However, we realized that we could further optimize on Solady because Solady
implements an “admin” feature that allows the user to upgrade the implementation
contract for the proxy. However, in the context of Kernel, this is actually
unnecessary, because Kernel itself already knows how to handle proxy upgrades.
Therefore, we were able to remove the admin feature, which removed another
SSTORE that costs around 20000 gas on deployment!


OPTIMIZING ECDSA SIGNATURE VALIDATION

Kernel, being a modular wallet, can handle different kinds of signature schemes,
but the most commonly used is still ECDSA which replicates the signing behavior
of EOA wallets. Therefore, optimizing the ECDSA verification flow can be very
impactful.

The first thing we did was to leverage Solady’s ECDSA recovery procedure, which
saves 282 gas comparing to OpenZeppelin. But we realized that there’s a much
bigger gain — again, since Kernel is so modular, even ECDSA verification is
implemented as a module (that way, it can be easily swapped for another
signature scheme such as multisig or RSA). However, by far the majority of
ZeroDev users use ECDSA for signatures, so they are paying for the plugin
dispatch cost for no reason.

That’s why we built Kernel Lite — a version of Kernel that hardcodes the ECDSA
validation logic. If you look at the benchmark numbers again, you will see that
Kernel Lite has by far the best numbers. We are currently auditing Kernel Lite
and will be releasing it to our SDK soon.


OPEN-SOURCING THE BENCHMARK

As much as we love Kernel, we want all SCWs to improve in gas efficiency so
users can enjoy cheaper transactions no matter which SCW they use. Therefore, we
are happy to open-source our benchmark in the hopes that it will help other SCW
implementations improve their performance.

We have taken great care to make the benchmark easy to use. To benchmark a SCW
implementation, you just need to create a test class that inherits from
TestBase.sol and implement a few functions. If you do so, please open a PR so we
can add your SCW to the list. Together, let’s make SCWs more efficient and save
gas for everyone!

--------------------------------------------------------------------------------

ZeroDev is hiring! If what we wrote here sounds interesting to you, drop us a
note :)




CREATING AA WALLETS WITH PASSKEYS AND USER IDS

August 24, 2023 · 3 min read
Derek Chiang
Founder & CEO of ZeroDev

At ZeroDev, we are always looking for more ways to help developers leverage
account abstraction (AA). Today we are happy to announce that we have partnered
up with Turnkey to enable two new types of AA wallets: passkey wallets and
server-side wallets.


PASSKEY WALLETS

Passkeys are becoming an increasingly popular alternative to passwords. With
passkeys, users authenticate with their hardware devices. If the device happens
to support biometrics, then the user can effectively “sign in” with fingerprints
or facial recognition alone.

In the context of ZeroDev, passkeys can be used to authenticate with AA wallets.
This enables a powerful experience where your users get to create self-custody
AA wallets using biometrics such as Apple’s Face ID or Touch ID, removing the
need for safekeeping seed phrases.

Here’s a simple demo of passkey wallets. You can also check out this demo from
our partner Goldfinch.

Check out these docs to get started with passkey AA wallets.


SERVER-SIDE WALLETS

Another common ask from our developers has been a way to “just create a wallet
for the user” — that is, creating a wallet for the user without requiring any
interaction from the user at all. This is typically useful in a Web 2.5
scenario, where the user is already identified with some Web2 credentials (e.g.
usernames or emails), and you simply want to create and associate an AA wallet
with the user.

To address this use case, we built “server-side wallets.” To create a wallet for
a user, all you need to do is to specify a “user ID” — a unique string that
identifies the user, which can be your database ID for example.

const { ECDSAProvider, getCustodialOwner } = require('@zerodev/sdk')

const ecdsaProvider = await ECDSAProvider.init({
    projectId,
    await getCustodialOwner('any-user-id')
})




Check out these docs to get started with server-side AA wallets.


PARTNERING WITH TURNKEY

Under the hood, the keys used in passkey and server-side wallets are secured by
Turnkey — a leading solution in secure key infrastructure.

Turnkey uses Trusted Execution Environments (TEE) to run its security-critical
services, such as verifying passkeys and generating keys. Given its
architecture, Turnkey itself is not able to access the raw private key materials
— only the users who are able to authenticate themselves are able to access
their private keys. In the case of passkey AA wallets, these are the end users
themselves. In the case of server-side wallets, these are your backend servers.

Zooming out, this is an interesting case study of decentralized access to
centralized infrastructure, which is an often under-explored area of blockchain
research. One parallel is validium rollups, which are rollups that store
transaction data off-chain on centralized infrastructure, sacrificing some
degree of decentralization for lower gas costs. In our case, we store keys on
centralized infrastructure, sacrificing some decentralization for better UX.
Whereas validium rollups derives security assurance from redundancy and
attestations, we derive security assurance from TEEs.


GET STARTED TODAY

Passkey wallets and server-side wallets have both received amazing feedback
during their private beta, and now we are incredibly excited to release them for
general usage. With these new solutions, AA has never been more accessible. Get
started with passkey AA wallets and server-side AA wallets today!




USING ZERODEV WITH PRIVY

August 17, 2023 · 2 min read
Derek Chiang
Founder & CEO of ZeroDev

Check out this post by Henri Stern (CEO of Privy) about the Privy + ZeroDev
integration.

Today, we are incredibly excited to announce our partnership with Privy, a
leading Web3 onboarding solution trusted by many well-known projects. The Privy
team deeply understands the importance of good UX, and it’s this fascination
with UX that led them to explore account abstraction (AA).

Privy is a great solution for onboarding users who have no prior Web3
experience, since it’s able to handle social logins and create an embedded
wallet for users with no wallets. However, users want to do things with their
wallet, and a user with an empty wallet just can’t do much since they are not
able to pay gas.

ZeroDev bridges that gap by bringing account abstraction (AA) to Privy. Users
using Privy’s embedded wallet can now easily send transactions without paying
gas, if the DApp is willing to sponsor gas for the user. Furthermore, users are
able to leverage all the amazing features that AA has to offer, including
transaction batching, paying gas in ERC20s, session keys, and more.

Given our shared commitment to good developer experience, Privy and ZeroDev have
developed a helper library for developers to seamlessly integrate the two
solutions. Get started here with Privy+ZeroDev today!




KERNEL V2 AND THE LESSONS WE LEARNED

May 30, 2023 · 7 min read
Derek Chiang
Founder & CEO of ZeroDev

Ever since releasing Kernel v1, we have seen a flurry of activities from
developers building novel plugins on Kernel. However, developers soon ran into
significant limitations that exposed some of the shortcomings of Kernel, which
prompted us to start working on Kernel v2.

In this blog post, we will dive into some of the issues with Kernel v1 and how
we addressed them in v2.

A fair warning: this blog is written for a technical audience who want to
understand the inner workings of Kernel, especially plugin developers. Most
users of ZeroDev do not need to understand what’s described in this blog.


ISSUES WITH KERNEL V1


VALIDATION AND EXECUTION ARE CLOSELY COUPLED

In Kernel v1, plugins modify how transactions are validated. Once validated, the
transactions are executed through a hardcoded execute function.

However, certain use cases turned out to require not just custom validation, but
also custom execution. For example, the default execution function allows both
call and delegatecall, and the latter makes it very hard to reason about the
security of a plugin. Therefore, some plugin developers wanted to disable
delegatecall altogether, but that was hard to do with Kernel v1.


INABILITY TO ADD CUSTOM FUNCTIONS

While the default execute function is meant to be flexible enough to execute
arbitrary transactions, sometimes there are legit needs to implement custom
functions. For example, let’s say there is a new ERC like ERC-1271 that requires
the implementation of new functions. With Kernel v1, there’s no way to
dynamically extend the contract to implement the new interface.


INABILITY TO CHANGE THE DEFAULT VALIDATION FUNCTION

Plugins in Kernel v1 introduce new “paths” for transactions to be validated, but
there wasn’t a way to update the “default path” — which validates ECDSA
signatures from the wallet owner. In other words, the wallet owner can always
execute transactions, regardless of plugins.

While this is normally desired, there are cases where the “default path” needs
to be modified or even outright blocked. For example, if you want to build a 2FA
account, it’s not enough to build a 2FA plugin — you also need to make sure that
the default ECDSA validation function is no longer effective, or it would defeat
the point of 2FA.


OVERLAPPING STORAGE BETWEEN KERNEL AND PLUGINS

In Kernel v1, plugins are invoked through delegatecall. To prevent storage
collision between plugins and the kernel, plugins are required to use
unstructured storage, sometimes known as “diamond storage.”

However, this requirement cannot be enforced, and a plugin needs to be carefully
audited to ensure that it’s in fact not using any storage outside of its area.
This places heavy burden on the user of the plugin as well as auditors.


DESIGN DECISIONS FOR KERNEL V2

Kernel v2 draws on the lessons we learnt from real-world applications building
on Kernel v1. At the core of Kernel v2’s architecture is two key design
decisions:

 * Separation of plugin storage from kernel storage.
 * Separation of validation from execution.


SEPARATION OF PLUGIN STORAGE FROM KERNEL STORAGE

In Kernel v1, plugins are invoked through delegatecall, which means plugins and
Kernel ultimately share the same storage. Therefore, plugin authors need to take
care to not “touch” the storage area of the Kernel, by using “diamond storage.”
This places burden on the plugin author, the plugin auditor, as well as the user
to ensure that the plugin correctly handles storage.

In Kernel v2, validator plugins are invoked through call. Therefore, validator
plugins have no access to the Kernel’s storage, vastly reducing the surface of
attack.


SEPARATION OF VALIDATION FROM EXECUTION

Whereas there are only “validation plugins” in Kernel v1, there are now two
classes of plugins in Kernel v2: validators and executors.

VALIDATORS

Validators are plugins that modify how transactions are validated. These plugins
are akin to the plugins in Kernel v1.

One notable difference is that in v2, it’s possible to replace the “default”
validator. For example, if you want to set up an account as 2FA, you would set
the default validator to the 2FA plugin, therefore replacing the default ECDSA
plugin. This makes it impossible to send transactions without going through 2FA.

EXECUTORS

Executors are plugins that add custom functions to Kernel. In particular, each
custom function is tied to a validator, meaning that a call to a custom function
is “routed” to a particular validator.

The ability to route each function to a different validator makes it possible to
implement ultra-fine-grained security policy. For example, you might want to add
a custom function to Kernel, but you ONLY want that function to be called if the
user goes through 2FA. With Kernel, you can set up routing so that the custom
function (executor) is routed through 2FA (validator).


HOW KERNEL V2 WORKS

In ERC-4337, a transaction (aka “UserOp”) is processed in two phases: a
validation phase and an execution phase. To understand how Kernel v2 works,
let’s walk through the lifecycle of a UserOp as processed by Kernel.


VALIDATION PHASE

In the validation phase, the EntryPoint calls the validateUserOp function on
Kernel. Transactions to Kernel can be executed in one of three "modes," as
indicated by the first few bytes of the UserOp's signature field.

 * Sudo mode (0x0) In sudo mode, Kernel's "default validator" is invoked. The
   default validator is a plugin that determines how transactions are validated
   by default (that is, if the transaction is not handled by another plugin). In
   ZeroDev, the default validator is normally set to the ECDSA validator, which
   approves a transaction if it's signed by the owner through ECDSA -- just like
   a regular transaction.
 * Plugin mode (0x1) In plugin mode, Kernel "looks up" the validator to use by
   the function selector from the calldata. The mapping between function
   selectors and validators are set through the "enable mode," which will be
   explained later. In any case, once a validator has been looked up, it's used
   to validate the transaction.
 * Enable mode (0x2) In enable mode, Kernel "enables" a validator, and it does
   so by associating the current function selector with the validator. The
   validator's address (keep in mind that plugins are smart contracts) is
   encoded inside the signature itself. Once enabled, the validator will be used
   to validate this and every subsequent invocation of the same function in
   plugin mode.


EXECUTION PHASE

In enable mode, Kernel actually associates with the function selector not just
the validator, but also the executor. Executors are smart contracts that
actually implement the function that corresponds to the selector. That is, when
you call the function kernel.someFunction(), the someFunction is actually
implemented in an executor, not the kernel itself.

When EntryPoint calls the function, Kernel uses a fallback function to look up
the executor associated with the function selector, then delegatecalls the
executor to execute the function. If you are familiar with EIP-2535 aka "Diamond
Proxies," you can think of executors as "facets."


NEXT STEPS

Today we are happy to announce that Kernel v2 has passed the initial audit and
therefore entered public beta. Here are some more resources for learning more
about Kernel:

 * Documentation for building plugins.
 * Code for Kernel v2.
 * Raw notes by Taek which this blog is based off of.
 * If you want to build some plugins, join our Discord and head to #plugin-devs
   where our community can help!




FIXING WEB3 WITH MPC+AA

May 4, 2023 · 6 min read
Derek Chiang
Founder & CEO of ZeroDev

(This post is cross-posted from the Portal blog and jointly authored with Parsa
Attari.)

Today, Portal and ZeroDev are excited to announce the development of the first
MPC + Account Abstraction (AA) wallet-as-a-service.



If you’ve been following the conversations around web3 UX, you know that MPC and
AA are the two solutions most commonly brought up as the “next big thing.” In
fact, we’ve seen countless arguments about which one is better.

But, far from being competing technologies, we believe MPC and AA are in fact
incredibly synergetic, and when combined can unlock a level of UX that’s
impossible to achieve with each technology alone.


WHAT ARE MPC AND ACCOUNT ABSTRACTION?

Let’s first clear up the concepts — what are MPC and AA exactly?


MULTI-PARTY COMPUTATION (MPC)

Multi-Party Computation (MPC) enables users to have multiple key shares across
devices instead of a single private key on a single device to manage access to a
crypto wallet. MPC protects users from phishing attacks and the risk of losing a
seed phrase by removing the single point of failure created by one key on one
device.

Portal offers a two key share solution backed by a Threshold Signature Scheme
(an application of MPC) to offer companies wallet-as-a-service. Portal wallets
have backup and recovery methods to protect users against lost and compromised
devices.


ACCOUNT ABSTRACTION (AA)

Today on Ethereum, every single transaction must be initiated by an Externally
Owned Account (EOA) — the kind of account managed by traditional wallets like
MetaMask. EOAs are deeply limiting, however, because the rules for validating
EOA transactions are hardcoded into the protocol itself and cannot be changed.

The goal of account abstraction is to enable transactions to be sent from
Contract Accounts (CA), which can program their own rules for validating
transactions. This unlocks the abilities to sponsor gas for users, batch
transactions, automate transactions…just to name a few.

ZeroDev offers a framework for quickly and safely developing AA wallets, by
providing a headless AA wallet (aka “Kernel”) and the associated “plugins” that
enable the aforementioned AA features.


WHY DO YOU NEED AA + MPC?

To understand why MPC and AA are synergetic, we must look at the lifecycle of a
transaction.

In short, a transaction’s life starts off-chain and ends on-chain. It’s this
duality that makes MPC + AA a complete solution for web3 UX.


MPC SIGNS TRANSACTIONS OFF-CHAIN

When you send a transaction, the first thing you do is to sign it. A normal
wallet such as MetaMask uses your private key stored locally on the device to
sign transactions. As previously stated, storing your private key on a single
device opens up opportunities for getting your key stolen or losing your key.

With an MPC wallet like Portal, the transaction is signed by multiple devices.
Furthermore, if you ever lose any one of the signing devices, another set of
devices can coordinate to recover your key share on the lost device.


AA VALIDATES TRANSACTIONS ON-CHAIN

Once a transaction has been signed, it’s then broadcast to a network of
validators, who then submit the transaction on-chain. This is where AA comes in.
For a normal transaction, the validator would check that the transaction is, in
fact, valid according to the protocol rules. For an AA transaction, the smart
contract wallet itself will check and affirm its validity.

For example, for a normal transaction, if the sender has no ETH, the transaction
is automatically rejected by the protocol. For an AA transaction, however, the
smart contract can effectively say: “well, even though the sender has no ETH,
this other account has agreed to pay ETH for this transaction, so I will let it
go through anyway.” This is why AA wallets have “superpowers” like gas
sponsorship.


HOW AA AND MPC BENEFIT FROM ONE ANOTHER

As the flow above demonstrates, while MPC makes it easy and secure to handle
keys, it does not fundamentally change how transactions are validated, which
means we don’t get the benefits of programmable transaction rules such as
letting someone else pay gas for you.

Meanwhile, while AA makes transaction validation incredibly flexible, it says
nothing about how keys are handled. Therefore, in a vanilla AA solution, the
user still needs to worry about securely storing and backing up keys.

By combining MPC and AA, you get easy and secure off-chain key management, plus
flexible on-chain transaction validation. See this table for a detailed
breakdown:




HOW MPC + AA WORKS

The clean separation between off-chain transaction signing and on-chain
transaction validation means that we were able to combine Portal and ZeroDev in
a very elegant way.


SETTING UP THE MPC+AA WALLET

As with the core Portal product, we start by generating key shares: one on the
user’s device and one on Portal’s backend. Portal manages backup and recovery in
the case of a new device or general recovery if a share is lost or leaked. All
of this is done off-chain, which means no gas!

Using the key generated by Portal, ZeroDev can now deterministically compute the
address of the AA wallet. Note that even though the AA wallet is a smart
contract wallet, it’s not actually deployed at this point — which means you are
still not paying any gas. Instead, you can already display the address to users
and use it to receive assets.


USING THE MPC+AA WALLET

When you send a transaction from this wallet, ZeroDev formats the transaction in
the ERC-4337 format (technically known as a “UserOperation”). This transaction
is then submitted to Portal for signing with MPC. Once the transaction is
signed, ZeroDev broadcasts the transaction to the ERC-4337 mempool. A network of
bundlers then compete to submit the transaction on-chain.

Once on-chain, the transaction is validated by ZeroDev’s wallet contract. From
the perspective of the ZeroDev contract, this transaction is no different than
if it was signed by a traditional wallet with a ECDSA key. The fact that the
transaction was signed in a multi-party fashion is completely transparent to the
ZeroDev wallet contract.


NEXT STEPS

While MPC and AA are both ground-breaking technologies poised to transform web3
UX, combining them takes your user experience to the next level by giving your
users a smart wallet whose key can be easily and securely managed.

The Portal+ZeroDev smart wallet is in development today. If you are interested
in this product, sign up for the beta waitlist. We can’t wait to see what you
will build with MPC+AA!




SESSION KEYS ARE THE JWTS OF WEB3

May 2, 2023 · 9 min read
Derek Chiang
Founder & CEO of ZeroDev

Web3 UX today faces many challenges. High gas costs, long transaction times, and
difficulties managing seed phrases are some of the most common issues that many
projects, including ZeroDev, strive to fix.

However, there’s one problem that lies at the heart of why Web3 just “doesn’t
feel right” to regular users, and yet is rarely discussed. The problem is that
authorization is broken on Web3.


AUTHENTICATION VS AUTHORIZATION

Before we delve deeper, let's clarify the difference between authentication and
authorization.

 * Authentication is the process of proving who you are. For instance, if you
   arrive at an NFT drop that you've been whitelisted for, how do you prove that
   you have indeed been whitelisted? Typically, the NFT drop will request you to
   sign a message. By cryptographically signing this message, you are
   authenticating to prove ownership of the whitelisted wallet.

 * Authorization, on the other hand, is proving what you can do. When you swap
   tokens on Uniswap, for example, it asks for your "approval" of the tokens you
   are swapping. By doing so, you are authorizing Uniswap to swap tokens on your
   behalf.


AUTHORIZATION ON WEB2

In Web2, authorization is usually managed with JSON Web Tokens (JWTs), primarily
in the context of OAuth.

Consider when we log into Zoom using Google. An OAuth sequence prompts you to
grant certain permissions, such as creating calendar events. Once approved,
Google generates a JWT containing these specific authorizations.

The JWT, bearing Google's digital signature for verification, then allows Zoom
to request corresponding services from Google's API on your behalf. As a result,
Zoom can automate actions for you like calendar event creation, but it can't do
anything else, like accessing your emails.

This process is so commonplace that people seldom pause to think about it.
However, when newcomers to Web3 start using DApps, they quickly realize a
daunting issue — authorization in Web3 is fundamentally flawed.


AUTHORIZATION IS BROKEN ON WEB3

The central idea of the JWT experience is that on Web2, it's possible to
authorize a third-party app (e.g., Zoom) to interact with a service (e.g.,
Google) on your behalf.

In Web3, however, there’s no common standard for authorization. As a result,
each application (or ERC) has to implement its own method for authorization.

For example, for ERC20 tokens, the approve(spender, amount) function authorizes
a spender to spend up to amount of your tokens. On the other hand, ERC721 tokens
use the setApprovalForAll(operator, approved) function to authorize an operator
to transfer all your NFTs in this collection.

More importantly, handling authorization at the contract level is deeply
limiting. For example, in the case of an NFT (ERC721) contract, what if you want
to authorize a third party to mint NFTs for you too? That would be helpful if
you wanna set up a bot that mints when an NFT collection is dropped. Since the
setApprovalForAll function only concerns with transferring NFTs, however, you
are out of luck.

What we need is a Web3 equivalent of JWTs — a universal standard for authorizing
third parties to perform actions on your behalf. This standard should be
flexible and widely interoperable, enabling DApps to "speak" this authorization
language with minimal modifications.

However, expecting all contracts to conform to the same authorization standard
is a significant challenge. As already mentioned, ERC20 and ERC721 contracts
handle authorizations differently, and most other contracts don't handle
authorizations at all.


USE THE WALLET, DUH

Turns out the best way to make authorization works for all contracts it to not
worry about contracts at all — rather, we do it with the wallet.

After all, the most obvious way to authorize someone to do something for you is
to, well, give them your seed phrase. That way, they can interact with any
contract on your behalf. Problem solved?

Of course, we all know that’s a terrible idea, since there’s no limit to what
the third party can do with your seed phrase. This is the equivalent of giving
someone key to your house when they ask to use your bathroom — it’s overkill and
unsafe.

So what if there was a way to give someone access to your wallet, but in such a
way that they could only send a limited set of transactions for you?


SESSION KEYS ARE THE JWTS OF WEB3

Enter session keys — a feature of ZeroDev AA wallets wherein you can create keys
that are scoped to only certain transactions, with an expiration time.

Session keys are the JWTs of Web3. Much like JWTs, session keys are
cryptographically signed — in this case, with your master key. Like JWTs,
session keys encode "scopes" within themselves that specify the actions they can
perform. Also, both JWTs and session keys can be created with an expiration time
to limit the consequences of keys being leaked.

While JWTs and session keys share many similarities, session keys are
fundamentally more powerful, because they are programmable, whereas JWTs are
defined by a standard that by definition doesn’t change. In that sense, session
keys can be thought of as programmable JWTs.

The table below summarizes how JWTs and session keys compare across key
dimensions.

FeatureJWTs (Web2)Session Keys (Web3)Granular PermissionsProvides permissions
for specific actions on the platform.Provides permissions for specific actions
across different contracts, while setting parameters for actions, like a maximum
gas amount, maximum transaction volume, etc.Expiration TimeJWTs have an
expiration time, requiring token refresh or user re-authentication.Session keys
also have an expiration time, ensuring temporary permissions.User
ExperienceAllows users to stay logged in across sessions and share sessions
across devices.Enables users to interact with a DApp within pre-set rules
without the need to sign every transaction.SecurityIf someone gains access to a
JWT, they would potentially have the same permissions as the user until the
token expires. The impact depends on the scope of the permissions granted by the
JWT, and could include unauthorized access to user data or actions performed on
their behalf.If a session key is compromised, the potential damage is limited by
the specific rules and parameters set for that key. For instance, a malicious
actor might be limited in the amount of tokens they can transact, the gas they
can spend, or the duration they can interact with a DApp.AdoptionWidely adopted
in Web2.A relatively new concept in Web3, but already used (with mostly
proprietary implementations) by several gaming projects including Loot Realms,
Briq, Topology, Cartridge, MatchboxDAO, and more.DecentralizationJWTs are issued
and verified by a centralized server.Session keys are issued and verified by the
user's wallet, and are entirely decentralized.InteroperabilityLimited to
platforms that support JWTs.Universally compatible with DApps on any blockchain
that supports AA walletsTrustTrust in the central server is required for
issuance and verification.Trust is not required as rules are set by the user and
signed with the user’s master key


EMPOWERING DAPPS WITH SESSION KEYS

It’s hard to overstate the impact of a flexible and interoperable means of
authorization. By taking advantage of session keys, DApps can create experiences
that are simply impossible to create otherwise.

In essence, session keys allow transactions that seem "automatic" from the
user's perspective. This can occur in two forms:

 * Skipping confirmations while the user is online. This is most useful in
   social and gaming applications, where frequent, small transactions are
   common. Each time a user has to sign a transaction, it disrupts the gaming
   experience. Using session keys, the user can pre-authorize a range of
   transactions, allowing them to enjoy the game uninterrupted.
 * Executing transactions when the user is offline. Consider a user who wants to
   ensure that they don't miss out on an NFT drop while they're asleep. The user
   can create a session key authorizing the purchase of the NFT at the drop
   time, even if they're not online. As another example, DeFi applications can
   use session keys to automatically exit risky positions for users so they
   don’t get liquidated.


USE SESSION KEYS WITH ZERODEV TODAY

At ZeroDev, we recognized the potential of session keys early on. After many
iterations, we now have what we believe to be the most advanced implementation
of session keys in the ecosystem.

We'll save the implementation details for a future blog post, but here's a brief
overview of what makes ZeroDev's session keys special:

 * ZeroDev session keys can be created off-chain. This means that creating a new
   session key does NOT require an on-chain transaction, enabling your
   applications to generate a large number of session keys without paying any
   gas.
 * ZeroDev session keys can define the scope of transactions based on various
   parameters such as contract addresses, function names, and ERC-165 interfaces
   (e.g., ERC20/ERC721), among others.
 * ZeroDev session keys can be authorized using only a public key. Thus, a
   client can create a public-private key pair and send just the public key to
   the master signer for authorization. This approach ensures that the private
   part of the session key never needs to be shared, minimizing the risk of
   leakage.

Session keys are available with ZeroDev today. Get started here and build some
groundbreaking DApps!


THE ROAD AHEAD

The quest to fix Web3 UX is a long one, but session keys are a significant step
towards this goal, offering a practical and secure solution to a major issue —
the lack of authorizations — that has been largely overlooked until now.

The widespread adoption of session keys will require collaboration across the
ecosystem. Wallet providers will need to support account abstraction (AA), and
DApps will need to be built to take advantage of session keys. However, the
benefits of dramatically improved user experience and security make the effort
worthwhile.

As more projects adopt session keys and AA in general, we will see the gap
between Web2 and Web3 experiences begin to close. ZeroDev is proud to be a part
of this journey, and we hope our contributions will make your users smile!




INTRODUCING KERNEL — MINIMAL & EXTENSIBLE SMART CONTRACT ACCOUNT FOR ERC-4337
WALLETS

April 25, 2023 · 8 min read
Derek Chiang
Founder & CEO of ZeroDev

With the launch of ERC-4337, we are seeing tremendous excitement from Web3
developers to build the next generation of crypto wallets using account
abstraction.

Whereas traditional wallets like MetaMask are powered by externally owned
accounts (EOA), account abstraction wallets are powered by smart contract
accounts (CA). These wallets will be able to sponsor gas for users, batch
transactions, support automatic payments (subscriptions)… overall enabling a
Web3 experience hitherto unimaginable.

While some wallet developers want to control the entire tech stack end-to-end,
most wallet developers we’ve met would rather focus on the end-user experience,
by building product features such as DeFi integrations, cross-chain transfers,
etc. Actually coding a smart contract account in Solidity, and making sure it’s
compatible with ERC-4337 and supports all the essential functionalities such as
validating signatures (ERC-1271) and bundling transactions, is time-consuming
and hard to get right for most wallet developers.


INTRODUCING KERNEL, A MINIMAL SMART CONTRACT ACCOUNT DESIGNED TO BE EXTENDED

Seeing this need, ZeroDev has developed an account abstraction wallet kernel.
The term kernel comes from the lingo of operating systems. The Linux kernel, for
example, is used by a wide range of operating systems such as Android, Raspberry
Pi, etc. The reason why the Linux kernel exists is so that different operations
systems do not have to build the basic OS functionalities (e.g. file systems and
networking) from scratch. Rather, operating systems builders can focus on
building the OS features that make the OS unique, whether it’s great UI,
integration with popular apps, or whatnot.

Similarly, the goal of the ZeroDev Kernel is so wallet developers do not have to
build the basic wallet functionalities from scratch. Specifically, the kernel
includes the following basic features that we consider essential to any AA
wallet:

 * Compatibility with ERC-4337
 * Validating signatures with ERC-1271
 * Batching transactions
 * Delegating calls

However, we recognize that wallet developers may also want to build additional
on-chain functionalities, and oftentimes these needs cannot even be anticipated
when the wallet was first built. For example, you might decide, after launching
your wallet, that a lot of your users are using the wallet with Web3 games, so
you’d like to support session keys (temporary keys with restricted permissions).
It would be very painful if you had to ask your users to upgrade their on-chain
smart contract accounts in order to support the new use case.

Therefore, we have built a plugin framework for developers to add
functionalities on top of the kernel, without needing to upgrade the account
itself.


KERNEL PLUGINS — ERC-4337-NATIVE SOLIDITY MODULES THAT MODIFY VALIDATION LOGIC

So what exactly is a plugin? It’s a Solidity contract that the kernel can
delegate to to modify the validation logic of the account.

That was a mouthful, so let’s look at an example. Let’s say, as a trivial
example, that you want to allow someone to manage your USDC and DAI balances.
You can create a contract like this (in pseudo-solidity):

contract StableCoinPlugin {
    function validateUserOp(UserOp op) returns bool {
        return op.to == USDC_CONTRACT || op.to == DAI_CONTRACT;
    }
}




Essentially, this plugin authorizes transactions that interact with the USDC and
DAI contracts.

Once this plugin has been deployed, you can sign an off-chain message
authorizing this plugin. You can then share the signed message with the person
or app that wants to manage your USDC/DAI. They will be able to send
transactions on your behalf, but only if those transactions interact with the
USDC and DAI contracts.

We will be diving deep into the plugin framework in a future blog post.


KERNEL MAKES IT EASY FOR USERS TO MIGRATE BETWEEN WALLETS

Most smart contract wallets are deployed as proxies, since proxies are a lot
cheaper to deploy than the underlying contract, but also because proxies allow
smart contract wallets to be upgraded.

One consequence of smart contract wallets being upgradable is that users are
free to switch between account implementations. For example, a user might be
onboarded to Web3 with a simple in-game wallet. The user might have accumulated
some valuable NFTs in the game, and instead of transferring the NFTs to a real
wallet, the user can simply upgrade its wallet implementation to a real wallet,
while keeping the same address.

While the idea is very appealing, in practice migrating between wallets can be
hard and unsafe. This is due to the issue with storage layouts. Consider these
two wallet implementations (in pseudo-solidity):

contract WalletA {
  address owner;
  uint256 nonce;
  // ...more code
}

contract WalletB {
  uint256 nonce;
  address owner;
  // ...more code
}




If a user starts with WalletA, then migrates to WalletB, its storage will be
corrupted because the original owner now sits on the slot of the nonce, and vice
versa. So in reality, before the migration, the user would need to wipe its own
storage, which is tricky and hard to get right.

ZeroDev Kernel is designed with migration in mind. To that end, Kernel uses
diamond storage — a technique that ensures that one wallet’s data storage won’t
collide with another wallet’s. Therefore, it’s perfectly safe to migrate either
from or to a wallet built on the kernel.

Note that Diamond storage is different than Diamond proxies (ERC-2535), which is
a much more ambitious and complex design. Here, we simply ensure that storage
layouts between different wallets don’t collide.

The fact that ZeroDev is perfectly migrate-able makes it perfect for building
onboarding wallets. Your users can onboard with ZeroDev and rest assured that
when they find an AA wallet they like, they can seamlessly migrate to that
wallet without having to change address. This is a 100x improvement over the
status quo of “exporting seed phrases,” which involves trusting some centralized
server to NOT store a copy of your seed phrase and hoping that the seed phrase
isn’t leaked somewhere along the process.


KERNEL VS SAFE

During beta testing, the most common question we got was understandably this:
why are you building a new smart contract account when you can just use Gnosis
Safe?

In fact, ZeroDev started with Safe. We contributed heavily to the reference Safe
4337 implementation, and used it all throughout our beta. However, we ran into
some major issues with Safe that blocked us from achieving our product
objectives:

 * Safe is complex. By all accounts, Safe is one of the largest smart contract
   codebases ever. Many features have been added over the years to satisfy a
   variety of organizational needs, and truthfully most of them are completely
   irrelevant for the kind of single-user AA use case that ZeroDev sets out to
   address.
 * Safe is inefficient as an ERC-4337 wallet. As the reference implementation
   shows, the only way to make Safe compatible with ERC-4337 was to do it
   through Safe’s “fallbacks” and “modules” mechanisms. This leads to a large
   amount of context switching and therefore high gas costs for even the most
   simple operations.

Ultimately, Safe was designed for a different use case — organizational
multisig. This is about as far from the single-user, single-sig use case that
ZeroDev is designed for. Therefore, we ultimately decided to bite the bullet and
implement a smart contract account optimized for retail AA users.

With Kernel, we now have a much simpler, much more efficient, and highly
extensible smart contract account, and our users couldn’t be happier.


KERNEL, ERC-6900, AND INTEROPERABILITY

One main goal with Kernel was to foster a thriving plugin ecosystem, but some
may be concerned that a plugin developed for Kernel will only work with Kernel.

As if anticipating that concern, our friends at Alchemy recently drafted
ERC-6900, titled “Modular Smart Contract Accounts and Plugins.” The goal of the
EIP is to define a common interface between smart contract accounts (e.g.
Kernel) and plugins.

We are very happy to see this development and we will be contributing to the
ERC. We are also glad to see that we’ve made many of the same design decisions
that the ERC authors did. As of today, Kernel is the closest thing to an
implementation of ERC-6900 that we know of, and we will be making Kernel fully
compatible with ERC-6900 once it’s finalized. That way, plugin and wallet
developers building on ZeroDev can rest assured that they are building on top of
an open standard and will enjoy great interoperability for their products.


START BUILDING ON KERNEL NOW

Today, we are excited to announce that Kernel has been open-sourced and audited,
and it’s now available for anyone to use. Being an open-source project, Kernel
is free for anyone to fork and extend. You can use ZeroDev to quickly spin up
Kernel-based AA wallets, and then extend the wallet’s functionalities using our
plugin framework. We are already building some of the most commonly asked-for
plugins including session keys, which we will dive into in a future blog post.

We are confident that Kernel will dramatically lower the barrier for building
wallets powered by account abstraction. We can’t wait to see what you build with
Kernel!




WHAT IS ERC-6492 AND WHY IT’S IMPORTANT FOR ACCOUNT ABSTRACTION

March 16, 2023 · 5 min read
Derek Chiang
Founder & CEO of ZeroDev

Unless you check new ERCs everyday (in which case, good for you), you probably
haven’t noticed this new ERC known as ERC-6492, innocuously named "Signature
Validation for Predeploy Contracts.” As this post is going to argue, ERC-6492 is
critical to the wide adoption of account abstraction and smart contract wallets
in general.

We will now explain the issue that ERC-6492 addresses, briefly touch on the
technicalities of how ERC-6492 solves the problem, and end by explaining why
it’s critical for key ecosystem projects such as Ethers and SIWE to adopt this
new standard.


TERMINOLOGY

For brevity, I will be using the following pairs of terms interchangeably, even
though it’s not technically accurate:

 * “AA” and “ERC-4337”
 * “AA wallets” and “smart contract wallets”
 * “Wallets” and “accounts”


THE CONTEXT

As I explained in a previous post, AA wallets are mostly compatible with
existing DApps since AA transactions look no different than normal transactions
from the perspective of the DApps, except for some edge cases.

Signature validation is a different story, however. As you know, many DApps
require some form of signing; OpenSea for instance requires the user to sign a
message before they can “log into” the DApp.

Since smart contract wallets have the flexibility to support different signing
schemes, there isn’t a universal way to validate signatures by a smart contract
wallet. Instead, there’s a standard ERC-1271 which defines a standard function
isValidSignature on a smart contract wallet so that the verifier (e.g. OpenSea)
can call the function to validate the signature, without needing to know
specifically what signing scheme the wallet uses.

This is all fine and good, and in fact ERC-1271 as a standard enjoys wide
adoption. Most popular DApps today, including OpenSea, already support it.


THE ISSUE

With the rise of ERC-4337, smart contract wallets are becoming increasingly
commonplace. One key optimization that ERC-4337 implements is counterfactual
deployment — namely, that we can compute the address of the account before the
underlying smart contract is actually deployed. As a result, a user can “create”
a ERC-4337 wallet without paying the deployment cost, so they can start
receiving assets, signing into DApps, etc. Only when the user sends their first
transaction that the contract is actually deployed.

While counterfactual deployment is normally very desirable, it becomes an issue
when the user needs to sign messages. To understand why, recall that in order to
validate a signature from a smart contract wallet, the verifier needs to call
isValidSignature on the wallet contract. However, since the wallet contract is
not actually deployed, it’s impossible to call that function! As a result, an
attempt to validate that signature will fail.


CONSEQUENCES

So what does this mean for the users? It means that it’s impossible to validate
signatures from ERC-4337 wallets until they are deployed. Therefore, for a new
ERC-4337 wallet that has not sent any transactions, it’s impossible to, say,
sign into OpenSea or any DApp that uses SIWE.

This is very bad because users who are new to Web3 want to sign into DApps and
look around before they spend any money on gas. Forcing a user to pay some gas
to deploy their wallets before they can see a DApp would be a major step
backwards comparing to the EOA experience today, where you can sign into DApps
even from an empty account.


SOLUTION

ZeroDev first encountered this problem when we were developing our WalletConnect
integration and realized that we couldn’t sign into OpenSea until we deployed
the wallet, which led to a lengthy discussion with many smart people in the 4337
ecosystem. Eventually, Ivo from Ambire came up with a great solution that turned
into ERC-6492.

On a high level, ERC-6492 works by using a UniversalSigValidator contract that
validates a signature as such:

 * Check if the signature ends with a sequence of magic bytes, which indicate
   that the signature is for a not-yet-deployed contract.
   * If so, the signature itself contains all the data necessary for deploying
     the contract, which comes down to an account factory address and the
     calldata for the factory.
   * UniversalSigValidator would then proceed to deploy the contract and calls
     isValidSignature on it to validate the signature.
 * If the magic bytes are not detected, then proceed as normal, which means:
   * Check if there’s contract code at the address. If so, proceed with
     ERC-1271.
   * Otherwise, assume that the account is an EOA and perform a ecrecover.

But wait! You might say. The signature verifier has to deploy the contract if it
doesn’t exist? Isn’t that incurring a lot of cost for the verifier?

The answer is no because the verifier will be using eth_call, which essentially
simulates the transaction without actually executing it on-chain.


NEXT STEPS

So who needs to implement ERC-6492? In short, it’s whoever that needs to verify
signatures, which is mostly DApps.

However, DApps don’t write everything from scratch. In fact, there are a few
libraries that most DApps use for handling signatures, so if these libraries
adopt ERC-6492, DApps would get to support ERC-6492 “for free.” Some of these
key libraries are:

 * Ethers: Ivo from Ambire has helpfully created a PR for supporting ERC-1271
   validation, which will be a stepping stone for ERC-6492.
 * SIWE: SIWE already supports ERC-1271, so we have created a PR that extends
   the support to ERC-6492, using Ivo’s library.

If you want to see the space move towards AA and smart contract wallets, there
are a few things you can do:

 * Upvote these PRs
 * Make your own PRs to libraries that validate signatures
 * And of course, if you are building a DApp, make sure that it can handle SCW
   signatures! DApps that work seamlessly with SCW will have an inherent
   advantage comparing to those that don’t, since more and more traffic are
   moving to SCW everyday.




ERC-4337 — MISCONCEPTIONS AND VALID CONCERNS

March 9, 2023 · 8 min read
Derek Chiang
Founder & CEO of ZeroDev

At ZeroDev, it’s our job to help devs learn and adopt AA, so naturally we have
come across a lot of questions, concerns, and objections.

In this post, I’d like to summarize some common pushbacks against ERC-4337 and
AA in general, and I will group them into three categories:

 * Misconceptions: things that are just not true.
 * Yes and no: somewhat true, but the reality is nuanced.
 * Valid concerns: real issues that need to be addressed.

Let’s dive in!


MISCONCEPTIONS


AA IS NO BIG DEAL BECAUSE SCW HAS BEEN AROUND FOR YEARS

Without AA, smart contract wallets like Safe/Argent are not “first class
citizens” on the blockchain, meaning that you cannot initiate transactions
directly from them. Rather, you have to do one of the following:

 * Call the SCW from a EOA, so you STILL have to own a dumb wallet before you
   can own a smart one.
 * Rely on a centralized relaying service to relay your transactions, which
   exposes you to risks like censorship, downtime, etc.

With AA however, you can directly send transactions from a SCW, the same way you
can directly send transactions from MetaMask. This makes it possible to use a
SCW as your only wallet, which is precisely what the next billion Web3 users
will do.


YOU STILL NEED A EOA TO OWN AN AA WALLET

This common point of confusion stems from the fact that most AA wallets today
are owned by a private key (just like EOA wallets), but it’s misguided because:

 * Private key ≠ EOA. While it’s true that each private key has a corresponding
   EOA, the key itself is just that — a key that can sign things. A typical AA
   wallet will store and safeguard a private key just like MetaMask does, and
   use the key to sign transactions for the smart contract account. The
   corresponding EOA, to the extent that it exists, is only used as a public key
   for validating signatures.
 * Since AA enables transactions to be validated with a smart contract, the
   validation logic can be arbitrary, so you don’t technically even need a
   private key. Here’s a proof of concept using fingerprints instead of private
   keys.


WE DON’T NEED AA IF WE HAVE MPC

The best way to think about MPC vs AA is:

 * MPC improves the key management experience.
 * AA improves the transaction experience.

With MPC, you effectively have a “virtual private key” without ever having to
store it somewhere, which is a huge improvement over the status quo of having to
write down a 12-word seed phrase.

AA is about what happens when you send a transaction — who pays gas? What tokens
are used to pay for gas? Who signs the transaction? All of these can be
abstracted away with AA.

As you can see, MPC and AA actually complement each other nicely — MPC saves the
user from having to deal with keys, while AA makes transactions smooth. In fact,
it’s precisely by combining MPC with AA that we are able to offer social AA
wallets.


YES AND NO


AA TRANSACTIONS ARE MORE EXPENSIVE

Since AA uses smart contract wallets, each transaction necessarily has some
overheads comparing to the equivalent EOA transaction. There’s also the cost of
deploying the smart contract wallet on-chain.

However, multiple factors lower the transaction cost in AA’s favor:

 * SCW has the ability to batch transactions, so what normally takes multiple
   transactions with EOA, may only take one transaction with a SCW. A classic
   example is when you interact with a DeFi protocol, where each action
   typically involves multiple transactions (e.g. approve → swap → deposit). In
   AA, all these can be done in one atomic transaction, thus saving gas.
 * ERC-4337 supports signature aggregation, so that multiple AA transactions can
   effectively “share” a signature, thus lowering the cost for each transaction.
   Here are some numbers from Vitalik.
 * ERC-4337 does not deploy the smart contract account until the user’s first
   transaction. Before then, the account exists “counterfactually” — it has an
   address even though it’s not really deployed. So your users can receive
   assets even without paying any deployment cost.

As a result, whether AA transactions or normal transactions cost more gas
actually depend on the workload. For some applications (notably DeFi), AA
transactions might wound up being cheaper!


AA IS NOT READY FOR PRODUCTION

There’s no doubt that anyone building something on AA/ERC-4337 today is a
trailblazer — there are not many prior examples to look to or patterns to borrow
from. In that sense, building something on AA certainly involves more technical
risks than building a classic DApp.

However, everything you need to build a full AA application, notably ERC-4337
itself, is already running in production/mainnet. We are at an inflection point
where you are either building one of the last non-AA applications, or one of the
first AA applications. The choice is yours.


AA IS NOT COMPATIBLE WITH EXISTING DAPPS

Before AA, there was “meta transactions” that could remove gas (or pay gas in
ERC20s) by using relayers that submit transactions on users’ behalf. The main
problem, however, was that DApp contracts had to use a helper function like
_msgSender() instead of the more intuitive msg.sender to get the address of the
transaction sender. Needless to say, most DApps did not do that, so the
compatibility of meta transactions were severely limited.

AA does not have this problem, however, which makes it compatible with the vast
majority of DApps. Where the compatibility breaks down, however, is when the
DApp asks the wallet to sign a message. It turns out that EOA signatures and
smart contract wallet signatures cannot be verified the same way, so there’s a
standard ERC-1271 that DApps are supposed to implement to be compatible with
smart contract wallets. Here’s an incomplete and likely outdated list of DApps
grouped by whether they support ERC-1271.

If a DApp requires message signing but doesn’t support ERC-1271, then AA indeed
won’t work with the DApp. Fortunately, the space is completely aligned that
ERC-1271 needs to be supported, and new DApps being written today typically
support ERC-1271 by default if they use libraries like OpenZeppelin.


ERC-4337 IS NOT REAL AA. WE SHOULD WAIT FOR REAL AA

When someone says that ERC-4337 is not “real” AA, they are typically referring
to the fact that ERC-4337 is NOT integrated into the blockchain protocol itself.
In contrast, new networks like zksync and StarkNet have “enshrined” AA as a part
of their protocols.

The reason why Ethereum and most other EVM chains have not enshrined AA is
two-fold:

 * Enshrining AA will be protocol-breaking, and therefore require a hard fork.
 * There’s no consensus over the best approach to implement AA, so it’s not even
   clear what we should be enshrining.

Enshrining AA into the protocol itself also means that every EVM chain has to
implement this breaking change, which can take a very very long time. In
contrast, since ERC-4337 is implemented as smart contracts, deploying to a new
chain is literally a matter of deploying a few smart contracts. That’s why
ERC-4337 is already running on all EVM chains today.

In any case, the distinction between “real AA” and “ERC-4337 AA” matters little
to the end users. From their perspective, their transactions “just work” either
way. Therefore, given the level of community buy-in for ERC-4337, it’s our best
hope for achieving AA on EVM blockchains in the near term.


VALID CONCERNS


ERC-4337 IS FAIRLY CENTRALIZED RIGHT NOW

In theory, ERC-4337 is designed such that anyone can spin up relayers (aka
“bundlers”), unlike previous relayer networks that are typically run by a single
entity.

In practice, however, most bundler implementations except for StackUp are not
production-ready, so most ERC-4337 traffic is going through StackUp today. This
is not unlike how most Ethereum traffic is going through Geth. Hopefully, this
will change as other bundlers go into production.


ERC-4337 MAY STILL CHANGE

While ERC-4337 has been deployed on mainnet, it’s not technically finalized. The
EIP is still in draft status, and the core team has acknowledged that the EIP
and the smart contracts could still change.

Fortunately, it’s expected that any changes to the EIP and core smart contracts
won’t affect the core account interface, so wallets that are compatible with
ERC-4337 today will most likely still be compatible with ERC-4337 in the future.


ERC-4337 HAS NOT BEEN FORMALLY VERIFIED

While ERC-4337 has been audited, it has NOT been formally verified, so one
cannot completely rule out the possibility that there are some critical security
issues.

Fortunately, there are teams working on the formal verification of ERC-4337
(with our very own taek being a major contributor). When ERC-4337 has been
formally verified, that’s when we expect to see it finalized.


THE BOTTOM LINE

Anyone building on AA today is a trailblazer taking on technical risks, no doubt
about it. But with risk comes reward — if properly executed, your project will
dwarf your competition in terms of usability.

At ZeroDev, we’ve developed an AA framework that dramatically shortens the time
— and reduces the risks — for devs to build wallets and DApps on AA. Check out
ZeroDev and start building the future of Web3 today!




WHAT CAN YOU DO WITH ACCOUNT ABSTRACTION?

December 17, 2022 · 8 min read
Derek Chiang
Founder & CEO of ZeroDev

As the saying goes, the only constant in Web3 is change. If you are building a
Web3 product, you need to stay on top of technological trends, in order to
identify new opportunities to grow and improve your product.

One emerging trend that you might have noticed is “account abstraction” (AA).
While there have been many great technical write-ups on account abstraction, I
would like to explain in this blog post the practical benefits of account
abstraction, or in other words, how you can leverage account abstraction to
improve your app.


ACCOUNT ABSTRACTION IN SIMPLE TERMS

First thing first: what does account abstraction actually mean?

On most blockchains today, transactions can only be sent from an "externally
owned account" (EOA), which is a fancy term to refer to wallets like MetaMask
that are created from a seed phrase. In other words, EOAs are the wallets
everyone has been using so far.

Account abstraction describes the ability for smart contracts to send and verify
transactions. The difference between a smart contract and an EOA is like the
difference between a computer and an abacus. Whereas an abacus can only be used
in a specific way, a computer can be programmed to perform arbitrary functions.
Similarly, whereas EOAs work in a pre-defined way, smart contract wallets (SCW)
can be programmed. This opens up exciting opportunities for you as a developer
to improve user experience (UX) and implement new product features, which we
will detail below.


SIDE NOTE ON SMART CONTRACT WALLETS

Some of you might be wondering: how is this different than smart contract
wallets like Gnosis Safe? Hasn't that been around for a while?

Yes, but the key breakthrough with account abstraction is that SCWs can finally
originate transactions. With Gnosis Safe, for example, the user still has to use
an EOA like MetaMask to issue transactions, which are then "routed through"
Gnosis Safe. Think controlling a computer with an abacus. This introduces a
significant barrier to using SCWs, which is why to this date SCWs like Gnosis
Safe are only used in high-security enterprise settings, and not in day-to-day
Web3 usage.


GAS SUCKS; AA FIXES IT

One of the biggest UX issues with EOA wallets is that users have to pay gas in
ETH (or whatever the native token is). This can be a significant hurdle,
especially for new users who are not familiar with cryptocurrencies and may not
even own any ETH.

As a classic example, let's say you are doing a "free mint" and you would like
your users to mint an NFT. While minting is free, gas is not. Someone new to
crypto would have to first acquire some ETH, which probably involves a KYC
process. More likely than not, they will simply give up, instead of engaging
with your app.

Another example is NFT games, where a user may have won or received some NFTs,
but can't do anything with them (such as trading or transferring the NFTs) since
they don't have the ETH to pay for gas.

Account abstraction addresses these issues by allowing users to skip gas
entirely, if a third party is willing to sponsor gas for them. In these
examples, you (the developer) can enable gas-less experiences for your users by
sponsoring their gas.

Account abstraction-enabled wallets can also pay gas in any ERC-20 tokens. For
DeFi applications, it's very common for a user to primarily be investing in
ERC-20 tokens such as UNI or USDC. With an EOA, the user would still have to own
a little bit of ETH (which they have to top up every now and then) in order to
pay gas for transactions. With account abstraction, the user can pay gas in the
tokens they already own!


SEED PHRASES ARE A NIGHTMARE

One of the biggest UX issues with EOA wallets is the need to safe-keep a seed
phrase. This is an incredibly difficult task for most people: seed phrases are
difficult to remember, and can be easily lost or stolen.

With smart contract wallets, there are many ways to solve this problem. One idea
is social recovery: a user can authorize a list of their friends or family
members to recover their account if they lose access. It's much easier to
remember who your best friends are than to remember 12 random words!

The flexibility of smart contract wallets also means that it can work with MPC,
so your users can simply login with a social account (e.g. Google) or
email/password.


BATCH TRANSACTIONS FOR FEWER CONFIRMATIONS

Another issue with EOA wallets is that each transaction is verified and executed
separately, which means long wait times and high gas fees. We have all had the
terrible experience of trying to do something simple, say swapping one token for
another, and yet having to confirm and wait for multiple transactions (e.g. an
"approve" into a "swap").

With account abstraction, however, multiple transactions can be batched together
into a single transaction. This significantly reduces the cost and wait time
associated with interacting with your app — your users can get things done in
one click.

Batching also makes your app safer by ensuring “atomicity” — that a multi-step
process either finishes or completely reverts, instead of getting stuck in a
“half-completed” state, e.g. “approve” succeeding but “swap” failing. The lack
of atomicity can lead to very tricky bugs in DApps, but it won’t be an issue
with AA.


BUILD INTERACTIVE APPS WITH SESSION KEYS

What if you are building a highly interactive application such as a game, where
prompting the user for confirmation would really disrupt their flow? Enter
session keys, which are temporary keys that can be used to send transactions for
a limited amount of time, with a limited scope of permissions.

Combining session keys with batching, your app can be sending far fewer
transactions, while skipping most approvals, making your UX approach that of
traditional Web2 applications.


TRANSACTION GUARDS

Sometimes you want to protect your wallets against misuse. With an AA wallet,
you can set up "transaction guards" – smart contracts that check transactions
that go through your wallet.

One example is spending limits. You might want to limit your daily spending to
$100, and for anything more than that you require a second signer (e.g. ledger).
This not only helps you rein in your NFT impulse buys, but also is a good way to
defend against hackers. With AA, spending limits can be easily implemented as a
transaction guard.


DELEGATE ASSETS

When you put crypto into a centralized product, you typically have no visibility
into what they are doing with your funds, which can result in disastrous
consequences (cough FTX cough). When you hold crypto in a self-custody wallet,
there's perfect visibility, but you need to personally initiate and sign every
transaction, which limits the potential of your crypto.

What if there's a third way? What if you can self-custody your funds, while
authorizing a third party to perform limited actions on your behalf?

A great example is collateralized loans like Compound and Aave. When you put
down collateral and take out a loan from these protocols, you need to
continuously monitor your loan and top up your collateral if necessary, in case
the price of your collateral token drops and your collateral gets liquidated.
This is a lot of work and stress.

With account abstraction, you can build applications such that your users can
delegate certain transactions for you to perform. If you were building a lending
app with account abstraction, for instance, your app could automatically close
your user's position when their collateral is in danger — all without them
having to give away custody of their assets. This works because the permissions
are enforced by smart contract wallets — the third party (e.g. your app) can
only perform the delegated transactions, and nothing else (such as stealing user
assets).


SUBSCRIPTIONS

As a particular use case of delegating assets, it's worth mentioning
subscriptions. With AA, your users can easily authorize you (the app) to pull
money from their accounts, but only up to a certain amount, at a given
frequency.


STATE OF ACCOUNT ABSTRACTION TODAY

By now, hopefully I have convinced you that account abstraction can vastly
improve the UX and functionality of your app. But is it ready today? Can you
actually build real products on account abstraction right now?

The answer is a resounding yes. New rollups such as StarkNet and zksync natively
support account abstraction, while ERC-4337 has brought account abstraction to
all EVM blockchains, including Ethereum, Polygon, Arbitrum, Optimism, Avalanche,
and more.

In a future blog post, I will dive deeper into ERC-4337 and explain how account
abstraction actually works. For now, my team at ZeroDev has created an SDK that
you can use today to enable account abstraction in your app. Give it a try now,
or join our new Discord and say hi!