We’ve all heard that “privacy UX sucks.” We tend to agree.
Users want to drive a car, not change the oil. We previously discussed how we abstract Aztec’s underlying UTXO architecture with Noir Lang and Aztec.nr, Aztec’s smart contract framework.
Today we’ll cover how we improve transaction processing via account abstraction and composable public-private design.
To date, protocols focusing on user privacy have exposed the underlying privacy architecture. And it turns out that users don’t like dealing with the nuts and bolts inside the machine.
We think user-friendly abstractions represent the future of intuitive UX in blockchains–a necessary step to bringing crypto to parity with web2. We’ll define transaction paths, explain what they mean, and explore how they future-proof the Aztec experience for developers and users.
Ethereum Accounts, A Primer
In Ethereum, every account is controlled by a private key, commonly derived from a mnemonic. If you’ve ever created an Ethereum wallet, you’ve seen the list of words you need to engrave, memorize, or at minimum jot down to secure your account.
Note that we’re talking about Ethereum externally-owned accounts here (EOA’s), not contract accounts, since on Ethereum, EOA’s are the only accounts that can initiate transactions.
When you initiate a transaction on Ethereum, the network expects a signature from the private key that controls the account. If you create a signature that matches the public key associated with the transaction, the transaction is submitted with a transaction payload that instructs the Ethereum Virtual Machine on exactly what functions to execute.
Account Abstraction, aka “Seed Phrases Ain’t It, Chief”
At Aztec Labs we’ve been thinking hard about forms of account authentication beyond signatures. The use of seed phrases has significant issues:
- No recovery: if you lose your phrase you may lose access to your account forever
- Confusing hygiene: you should never, ever, ever copy your phrase to your computer’s clipboard using the copy and paste feature
- Single point of failure: anyone who has your key has full access to your account
So how do we get around seed phrases and private keys as the sole forms of account validation? Seed phrases are just one very secure but very flawed form of account validation. There are myriad methods of account validation, spanning the spectrum from very secure to totally insecure, from intuitive to confusing, including but not limited to:
- Key sharding
- Plaintext passwords
- TouchID and other biometric signature schemes
Keep in mind account validation can be as secure as you want it to be. One simple account validation scheme would be: “If you click the ‘yes’ button the account is validated.” It wouldn’t be secure AT ALL, but you could do it!
Account abstraction is confusing as a term, since it encompasses “everything but seed phrases,” but the holy grail of authentication would include three factors:
- Something you know (like a password)
- Something you have (like a hardware wallet or Yubi Key)
- Something you are (like biometrics or a decentralized proof of identity scheme)
Aztec allows for combining all three.
But Aztec’s improvements to Ethereum go beyond the implementation of alternate authentication schemes.
Aztec’s transaction anatomy is also a bit different — users send proofs of computation rather than signing transactions from an EOA.
Here is the flow diagram for an Aztec transaction:
- User connects wallet to app
- User expresses transaction intent
- App supplies transaction info to wallet
- Wallet executes function
- Prove account interaction
- Prove function
- Wallet generates kernel proof
- App receives kernel proof
- Wallet broadcasts transaction to network
- Aztec node includes transaction in rollup block
- Ethereum finalizes L1 block
We’ll talk through each in turn.
Anatomy of a private Aztec transaction
Before we carve the patient open and look at its guts, know that there are two transaction paths within Aztec: private transactions and public transactions, each with their own attributes.
At the center of these transactions is something called the kernel circuit. The kernel circuit is the beating heart of the Aztec system, and validates private transactions. We’ll get back to it in a second.
For now let’s talk about what a blockchain transaction in general is:
- Authorization: typically a signature, but as we’ll see can be many things
- Intent: typically a transaction payload that includes instructions such as FROM, RECIPIENT, SIGNATURE, and fee information
We already discussed how Aztec allows for new forms of authorization, but how does it process transactions?
Aztec is a completely new execution environment beyond the EVM, and uses client-based zero knowledge proofs to prove individual transactions. That means the application developer’s job is to constrain functions appropriately and prove user intent.
Application developers can constrain user intents by writing smart contracts using Aztec.nr. In the private transfer example, the circuits behind the smart contract are checking a few conditions:
- Does the user own >10 DAI?
- If so, destroy 10 DAI of their notes by creating nullifiers against them
- Create a new 10 DAI note for the transfer recipient
- Broadcast and encrypt the message containing the 10 DAI note
The nullifier, new note, an encrypted log are all made public, but kept encrypted, such that the public information tells you nothing about what happened. Roughly all an observer can see is “a transaction happened here but I’m not sure what.”
That’s the core of Aztec’s value proposition — we know with mathematical certainty transactions are happening that follow blockchain rules, but we can’t derive any information about those transactions.
📕 See our previous piece on how Aztec’s privacy abstraction works
The path for public transactions is slightly different, as Aztec relies on the familiar Ethereum account-based model for public transactions.
The key to Aztec’s public transactions are unconstrained functions–Aztec’s public VM bytecode. Unconstrained functions just do “normal code stuff.” And by “normal code stuff” we mean simply execution code rather than proving execution as in Aztec’s private execution path. Unconstrained functions don’t lay down constraints. They just executes code.
If Aztec is a world computer, then unconstrained functions are the instructions the computer understands. Just like the EVM executes Solidity, the Aztec VM executes Aztec bytecode.
One key difference between the private and public execution paths is when code gets executed. In the private transaction example, code must be executed and proven locally–that is, before proof of the transaction is sent to Aztec’s network of nodes.
In the public execution path, the wallet has to receive authorization, but doesn’t process the transaction, instead sending transaction details onward to an Aztec node which then creates a proof of execution and inserts the proof into a block.
Because privacy is no longer a concern with public transactions, they can be sent unencrypted to the node to do efficient batch processing, rather than relying on a user’s local device.
Privacy UX sucks. Zero knowledge is complicated. Our goal is two-fold:
- Simplify DevEx with tools like Aztec.nr — a smart contract framework that makes it intuitive to reason about private state management
- Simplify UX with abstractions that help users access the blockchain with better tools than EOA signature validation
Great privacy-first applications will be built on the backs of best-in-class tooling that makes it easy to build powerful software that makes preserving privacy smooth and intuitive for users.
That means more code, less cryptography.
Keep in touch
For more technical news on Aztec and Noir, join our e-mail newsletter:
Join our team
Aztec Labs is on the lookout for talented engineers, cryptographers, and business people to accelerate our vision of encrypted Ethereum.
👪 If joining our mission to bring scalable privacy to Ethereum excites you, check out our open roles.
And continue the conversation with us on Twitter.