Awesome
[!IMPORTANT]
This repo is for demo purposes only.
Account Abstraction
<br/> <p align="center"> <img src="./img/ethereum/account-abstraction-again.png" width="500" alt="aa"> </p> <br/>- Account Abstraction
- Getting Started
- Quickstart
- Example Deployments
- Account Abstraction zkSync Contract Deployment Flow
- FAQ
- Acknowledgements
- Disclaimer
What is Account Abstraction?
EoAs are now smart contracts. That's all account abstraction is.
But what does that mean?
Right now, every single transaction in web3 stems from a single private key.
account abstraction means that not only the execution of a transaction can be arbitrarily complex computation logic as specified by the EVM, but also the authorization logic.
What's this repo show?
- A minimal EVM "Smart Wallet" using alt-mempool AA
- We even send a transactoin to the
EntryPoint.sol
- We even send a transactoin to the
- A minimal zkSync "Smart Wallet" using native AA
- zkSync uses native AA, which is slightly different than ERC-4337
- We do send our zkSync transaction to the alt-mempool
What does this repo not show?
- Sending your userop to the alt-mempool
- You can learn how to do this via the alchemy docs
Getting Started
Requirements
- git
- You'll know you did it right if you can run
git --version
and you see a response likegit version x.x.x
- You'll know you did it right if you can run
- foundry
- You'll know you did it right if you can run
forge --version
and you see a response likeforge 0.2.0 (816e00b 2023-03-16T00:05:26.396218Z)
- You'll know you did it right if you can run
- foundry-zksync
- You'll know you did it right if you can run
forge-zksync --help
and you seezksync
somewhere in the output
- You'll know you did it right if you can run
Installation
git clone https://github.com/PatrickAlphaC/minimal-account-abstraction
cd minimal-account-abstraction
make
Quickstart
Vanilla Foundry
foundryup
make test
Deploy - Arbitrum
make deployEth
User operation - Arbitrum
make sendUserOp
zkSync Foundry
foundryup-zksync
make zkbuild
make zktest
Deploy - zkSync local network
Additional Requirements
- npx & npm
- You'll know you did it right if you can run
npm --version
and you see a response like7.24.0
andnpx --version
and you see a response like8.1.0
.
- You'll know you did it right if you can run
- yarn
- You'll know you did it right if you can run
yarn --version
and you see a response like1.22.17
.
- You'll know you did it right if you can run
- docker
- You'll know you did it right if you can run
docker --version
and you see a response likeDocker version 20.10.7, build f0df350
. - Then, you'll want the daemon running, you'll know it's running if you can run
docker --info
and in the output you'll see something like the following to know it's running:
- You'll know you did it right if you can run
Client:
Context: default
Debug Mode: false
Install dependencies:
yarn
Setup - local node
# Select `in memory node` and nothing else
npx zksync-cli dev start
Deploy - local node
[!IMPORTANT]
Never have a private key associated with real funds in plaintext.
# Setup your .env file, see the .env.example for an example
make zkdeploy
Note: Sending an account abstraction transaction doesn't work on the local network, because we don't have the system contracts setup on the local network.
Deploy - zkSync Sepolia or Mainnet
Make sure your wallet has at least 0.01 zkSync ETH in it.
- Encrypt your key
Add your PRIVATE_KEY
and PRIVATE_KEY_PASSWORD
to your .env
file, then run:
make encryptKey
[!IMPORTANT] NOW DELETE YOUR PRIVATE KEY AND PASSWORD FROM YOUR
.env
FILE!!! Don't push your.encryptedKey.json
up to GitHub either!
- Un-Comment the Sepolia or Mainnet section (depending on which you'd like to use) of
DeployZkMinimal.ts
andSendAATx.ts
:
// // Sepolia - uncomment to use
- Deploy the contract
make zkdeploy
You'll get an output like:
zkMinimalAccount deployed to: 0x4768d649Da9927a8b3842108117eC0ca7Bc6953f
With transaction hash: 0x103f6d894c20620dc632896799960d06ca37e722d20682ca824d428579ba157c
Grab the address of the zkMinimalAccount
and add it to the ZK_MINIMAL_ADDRESS
of SendAATx.ts
.
- Fund your account
Send it 0.002
zkSync sepolia ETH.
- Send an AA transaction
make sendTx
You'll get an out put like this:
Let's do this!
Setting up contract details...
The owner of this minimal account is: 0x643315C9Be056cDEA171F4e7b2222a4ddaB9F88D
Populating transaction...
Signing transaction...
The minimal account nonce before the first tx is 0
Transaction sent from minimal account with hash 0xec7800e3a01d5ba5e472396127b656f7058cdcc5a1bd292b2b49f76aa19548c8
The account's nonce after the first tx is 1
Example Deployments
zkSync (Sepolia)
Ethereum (Arbitrum)
Account Abstraction zkSync Contract Deployment Flow
First time
- Calls
createAccount
orcreate2Account
on theCONTRACT_DEPLOYER
system contract- This will deploy the contract to the L1.
- Mark the contract hash in the
KnownCodesStorage
contract - Mark it as an AA contract
- Example
- Notice 6 logs emitted?
Subsequent times
- Calls
createAccount
orcreate2Account
on theCONTRACT_DEPLOYER
system contract- The
CONTRACT_DEPLOYER
will check and see it's deployed this hash before - It will put in another system contract that this address is associated with the first has
- Example
- Only 3 logs emitted!
- The
FAQ
What if I don't add the contract hash to factory deps?
The transaction will revert. The ContractDeployer
checks to see if it knows the hash, and if not, it will revert! The ContractDeployer
calls the KnownCodesStorage
contract, which keeps track of every single contract hash deployed on the zkSync chain. Crazy right!
Why can't we do these deployments with foundry or cast?
Foundry and cast don't have support for the factoryDeps
transaction field, or support for type 113
transactions.
Why can I use forge create --legacy
to deploy a regular contract?
foundry-zksync
is smart enough to see a legacy deployment (when you send a transaction to the 0 address with data) and transform it into a contract call to the deployer. It's only smart enough for legacy deployments as of today, not the new EIP-1559
type 2 transactions or account creation.
Acknowledgements
Disclaimer
This codebase is for educational purposes only and has not undergone a security review.