Dare to wonder and make wonders?
Drop us a message.
Encode Club hosted a great hackathon focused on Layer 2 scaling solutions - Layer Hack. The hackathon lasted for nearly a month (Oct. 17 - Nov. 13), and was sponsored by AltLayer, Boba Network, Metis, and zkSync - each sponsor had their track with its own topic.
Out of those four tracks, what grabbed our attention was the zkSync’s Account Abstraction (AA) challenge. The open-endedness of the challenge itself - long story short - “build something awesome” (at least that’s how we understood it).
And so, the 3327 Unit’s - HackOps team decided to gear up and tackle this challenge.
Why did we choose the AA track, what’s the significance of this concept, and most importantly, what have we built? - Stay tuned and be amazed!
In the current Ethereum Virtual Machine (EVM) based systems, there are two distinct types of accounts:
There exist multiple differences between them, but the ones we will focus on are the fact that only EOAs can initiate transactions and that their validation logic cannot be altered.
Note: We refer to validation logic as the set of rules that need to be obeyed in order for the transaction to be accepted by the network.
EOAs’ hardcoded validation logic checks whether the transaction was signed by the private key that corresponds to the address of the EOA. In contrast, the validation logic of an SCA can be anything - i.e. multisig.
Having arbitrary logic introduces additional complexity, but it has the benefit of the owner setting their own custom security standards.
For example, an AA owner can add a “session key” for a specific Decentralized Application (DApp) in one transaction and continue interacting with the DApp without manually signing every transaction.
The session key’s authority would be limited to a set of specific actions and/or time-limited and/or until a specific range of on-chain states is reached. The applications of this concept are maybe most suitable for on-chain games, where the gamers do not want to break the flow of the game, but any DApp can potentially improve its User Experience (UX) with AA.
There exist several Ethereum Improvement Proposals (EIPs) dating back to 2016 that tackle the AA problem, but it is not known when full AA support will be implemented in Ethereum.
However, in zkSync v2, things are already a lot better:
“Accounts in zkSync 2.0 can initiate transactions, like an EOA, but can also have arbitrary logic implemented in them, like a smart contract. This feature is called "account abstraction" and it aims to resolve the issues described above.” (Taken from the docs)
Official documentation for zkSync V2
Reading the documentation tells us that the (simplified) flow for each transaction consists of the following ordered steps:
There are, however, limitations to what the validation logic can do, more precisely, what storage slots it can access. In the zkSync’s implementation, the validation logic of an AA (that has the address of AA_addr) can touch:
And so, one needs to carefully structure the data that is stored across multiple contracts.
There were multiple great ideas that we had for this hackathon - some of which we started researching and implementing after the hackathon.
For Layer Hack, we chose to create a system where the owner of an AA can modify its validation logic according to their always-evolving needs.
Full code is available at 0x3327/layerhack_2022, but we will cover the basic concepts here.
At the center of the AAP is the IPlugin
interface that we have defined as such:
interface IPlugin{
function isValid(Transaction calldata _tx) external view returns (bool);
}
Essentially, the plugin receives the complete transaction and has to decide, based on the transaction’s fields as well as its own internal state, whether it accepts the transaction.
Each AA has a list of enabled plugin types (contracts that support the IPlugin
interface), which are called in its validation logic.
We chose to implement a LimiterPlugin
type where the owner gives an ETH spending limit to a spender address. The spender can then make transactions that have a value lesser than the limit that is imposed.
contract LimiterPlugin is IPlugin {
mapping(address => mapping (address => uint )) public activeLimits;
function isValid(Transaction calldata _transaction)
public
view
override
returns (bool)
{
bytes32 txHash = _transaction.encodeHash();
address accountAddr = address(uint160(_transaction.from));
require(_transaction.signature.length == 65, "Signature length is incorrect");
address signerAddr = ECDSA.recover(txHash, _transaction.signature[0:65]);
return activeLimits[accountAddr][signerAddr] > _transaction.reserved[1];
}
}
Note what storage slots we are accessing in the isValid function - only the slots that our AA can touch ( activeLimits[accountAddr]
).
Additionally, this plugin has other functions that need to be called by the AA in order to activate/deactivate these limits for a list of spenders.
Can a spender increase their own limit? The answer is no because a segment of the AA’s validation logic disallows it - only the owner has the exclusive right to interact with the plugin contracts.
We would like to give a big shoutout to Encode Club for organizing this eye-opening hackathon, as well as zkSync for working towards implementing AA which will be a game-changer for the whole UX and blockchain adoption.
Currently, we are continuing our research on ideas that use zkSync’s AA mechanism, and we will publish our results soon.
In the meanwhile, let’s connect via Discord or Twitter - We would love to hear from you.
COMMENTS (0)