'A Developer's Guide to Account Abstraction' - Sam Wilson & Ansgar Dietrich
ETHGlobal·Sat, Oct 9, 2021, 12:00 AM
An overview of account abstraction, a proposed change that would allow dapps to pay fees for users.
Transcript
which is gonna be presented by sam and anskar uh who will share an overview of account abstraction a proposed change that would allow deps to pay fees for users oh i see we're a little bit early i hope sam and anskar are there already sam and scar welcome in case you're there hi i said audio cut out for a second okay um i don't yet see a shared screen here we go okay so um we're here to oh let me let me also share with you my video hi everyone uh so we are here today to talk a little bit about account abstraction um and the first thing we want to do is just briefly to talk about what what even is account obstruction in general uh and that and so as you're all probably aware of and the whole idea of ethereum was to move from bitcoin where you don't have like programmability and especially you have always fixed the facts right the transaction can always only send value from a to b or like from one utxo to another utxos for bitcoin whereas in ethereum you have contracts and what contracts give you is full programmability however on ethereum today that is only true for the effects of a transaction so the actual validity on ethereum when when is a transaction valid and can be included on chain is always statically analyzed that is only like a signature check and ecdsa signature and then announce check whereas on bitcoin you do funny enough only enough have like a limited programmability with like the bitcoin scripting language it's not true and complete in everything but at least there's something so you can have native multi-six on bitcoin you can't have them on ethereum and now ethereum with account obstruction basically just is aiming at fixing exactly this so you just um add programmable validity on top of ethereum as you have today and basically why do we want to talk about it well we recently published an eip is exactly on account abstraction and then this is also like a good point to briefly talk about the wii so who are we um sam and i we are here on the call uh today and uh to present uh to you uh this the cip and then we we created the erp together with the rest of the quilts team that is a research team within um consensus and with two together with vitalik and our focus in quilt has been mainly on ethereum ii in the last year or two um and we actually came from the world amateur maybe you heard the the words of like execution environments right that was one of the big things we we looked into and but it was more clear that like most likely in it too initially we will have like some especially with phase 1.5 where we just bring the the it one as as it is today into the two context first before we do all these more advanced things and so we looked into how can we bring like the best of these like more advanced e2 features already to ethereum today and this is what led us to account abstraction but very importantly don't panic um we we really try to make sure that this is like a very simple overview we don't go too much into the technical details so let's start uh maybe with like a simple motivating example say you're a user on ethereum and there's a contract maybe it's like a multi-sig maybe it's a smart contract wallet right something where you want to send it's basically your contract you want to send from that contract a transaction to a different like target contract or account or whatever what you have to do today is you have to like own an account an extra account on the ethereum mainnet that has ether in it then you have to send it to our transaction to the contract and then the contract has to send like another transaction to the target if you don't own a contract which you can in an account but you can do instead you can use a relayer but then like the relayer needs to have an account and a relayer needs to send a transaction and then the contract has to pay the re-layer and that just adds even more overhead right um basically the the idea behind the conduct section is right what we want to get to is this simple picture right you have a user the user can just immediately initiate a transaction at a contract and then the contract pays for the transaction the contract does whatever you want the contract to do right and this this is this is the goal and so the question is right how do we get there and what does it look like um yeah so this is what uh this is what solidity could look like not what it will look like and this is based off of an early prototype that quilt put together of uh an earlier version of the eip so the first thing you're going to notice is the new account keyword before contract and that signifies that this is an account abstraction contract um the next thing you'll note is that the signatures are embedded in the call data which you can see in the transfer function signature this is a two of two multisig so you end up getting two different signature arguments in the call data um we've skipped over in this slide but those signatures would be checked in the perform validation step which is followed by pay gas pay gas is a new op code we're going to get into later but essentially it determines how much the contract is willing to pay for the transaction once pay gas is finished you move on to regular transaction execution we have a series of examples that we think are really good at representing uh account abstraction and what it brings these are not the only use uses for account abstraction they're just illustrative examples so i want to first talk about the smart contract wallet which i'm sure most of you are familiar with but for those who aren't it's a wallet which is implemented on chain that provides additional features like social recovery batch transactions and other cool things you can't do with an eoa gnosis safe and urgent are two existing examples so it's clearly possible to implement it but and this is a big bud they still require an eoa to pay for gas with aaa smart contract wallets can pay for their own gas and you don't need the eoa anymore the second use case we'd like to look at are mixers which anonymize transactions by batching deposits and then allowing different accounts to then claim those deposits tornado.cash is a prominent example today but the problem with mixtures as they exist today is that you need to you need eth in your account to claim the funds um so you need external relays again with aaa the withdrawn funds the anonymized funds can pay for the transaction and you don't need the external relayers a third example um is what we call like in-app tokens and so you can you can imagine that uh you have a dab and the dab just like the the the developer of the dev wants users to be able to just interact with the dab directly without having to like worry about the ethereum chain and in ether and and basically jump to all these hoops right and so the idea is that you could just have users like pay for interactions with the blockchain directly in in like a debt token so that could be if it's a game that could be in in-game currency or if it's like a different debt that could be whatever kind of token you just can directly pay the contract like and then the contract just sponsors your transaction and so you can still you still get like all the benefits from directly interacting with the blockchain you don't have to go just through some in direction but you don't need to need to like learn about all these or like need to to to basically ever care about mainnet and like for for things like onboarding you could while you could obviously do it with your own account and with ether you can always also just use like a signed message from from like the the the web creator they could basically just sign likes give you like a signed onboarding statement and then you can just go directly to chain again and execute that and be onboarded in the contract so um and and then the tokens obviously can be they could that can be real economic value tied to it okay it can also be simply used as a limiting mechanism this is like a very extensive use case which we think could have many different different applications and also with a obviously it's all just native and then the the last use case which we call default arbitrage this is somewhat also to highlight like i would say the limitations of of account obstruction but the idea let's start with that is obviously um i i think you all know what defa is right and so often times they are just simple arbitrage spots that look at or like try to find opportunities to do have simple profitable arbitrage trades um all within one transaction and so what you'll commonly see on on manual today is like a pattern where these spots send like a transaction to like one of their own deployed contracts then the contract checks for opportunities for for arbitrage and if if they don't find any they just exit immediately but the issue is that obviously that is inefficient because then you have like a lot of these dummy transactions that just exit immediately they just go to the contract check for opportunities don't find any exit but they still obviously take up all the block space right and so the idea is with aa what you would hope to do is you could also just like tie the validity um of this transaction to the existence of the arbitrage opportunity so they cannot ever make it to a chain unless they are also willing to to actually do something right and so that that would be an advantage but and this is important and we'll talk about it later a little bit more uh for for many of the more advanced d5 use cases obviously your validity depends on probably on the state of multiple contracts and then it becomes very challenging to make these use cases work so this is like on the like most advanced side of things and so um one question that we often get before we then obviously next next thing will be we talk about the actual technicalities of the erp but one question that we always get is like how does account obstruction relate to all these other proposals there have been quite a few other proposals in the in recent times that also want to use solve some of the usability um issues on ethereum and specifically these two are like somewhat related and so we want to briefly mention them so the first one is erp2711 this is sponsored expiring and batch transactions which is a really interesting erp it is mostly orthogonal to aaa and so obviously aa itself decides if you want to pay for a transaction with sponsor transactions decide like who pays pays for that right it is important though to note that this specific erp as it is proposed today is not compatible in the sense you could still have both on chain but aa contracts could not be sponsors then under this eip and so we were working on a alternative specifically sam is working on an alternative erp as a pre-compile that also does the same thing it basically authenticates a message and then sets the message sender but it would be compatible and then uh last thing obviously this erp had like multiple individual proposals and so it is important to note that batch transactions that's als that is definitely awesome for existing uh accounts today but to know it is to note that like a a contract as they are like fully programmable they are like basically natively able to do bad transactions right you can just send them a bunch of call data and they can then do whatever processing they want and send multiple sub transactions that's that's fine so you get batch transactions natively with with account obstruction and then the other erp i want to just briefly mention that's uh 2803 that's rich transactions that's also really interesting in case you have heard of it that do look into it but it is um it only brings like very limited execution capabilities to eoas and ins and most importantly it does not give you programmable validity what a is all about right so what it does is basically it lets you execute some code against your account account which is interesting but it's mainly useful for batch transactions and again you get those for free with account abstraction so let's now dive into the actual technicalities of like how does the erp work and so it's important to note that account obstruction has been around like forever is a strong word obviously in the blockchain space but um so there's uh one of one very early ap erp 86 that was authored by vitalik and that's from february to 2017 already and that was called abstraction of transaction origin and signature that's like basically like uh where where this already started and the idea obviously can be traced back even further the challenge so far has been that uh like implementing account restriction is a rather extensive change to a protocol and it's hard to reason about the exact safety implications right there are all these different actors and like you could have safety at multiple levels and so this is the key issue that has to be addressed for like a counter protection to actually make it edge to mainnet and so our approach was to like split the changes of the erp into two parts the first one is the protocol consensus changes right this is what like every node in the network has to support you like be able to continue to process blocks after after a potential fork and we would really like wanted to keep those minimal so you can like very clearly see that those are safe that there's no problem with them and then the other side like is for a and i'll talk about that in a second is that um there are some issues around just networking and propagation of transactions and so we we have we focus on like very restrictive easy to reason about memphis rules in the beginning and then the idea is to then iterately iteratively change those rules to add additional features and we'll go through them now in a second so um first like let's have a quick look at the protocol changes so there are two main ones the first one is the introduction of a new transaction type um people are often often asked with aaa there is not actually like there is no such thing as an aaa contract so there are still only two kind of of accounts they are externally owned accounts often called eoas and end contracts this doesn't change what we basically do is we add like new capabilities to the existing contract type um what we do is we introduce a new transaction type what even is a transaction type until now there's only one type of transaction in ethereum but there's already another eip called 2718 and that's typed transactions so that introduces the option to like have multiple different forms of transactions that will also be used for example with um yeah one five f9 if you if you're if you know about this one and this is the this is basically the mechanism that this uses and also account objection would use that and introduce a new transaction type for account abstraction specifically and like uh just to very briefly compare the two like current transaction on ethereum i i i just added a little list basically it's an encoding of the following fields basically you have nones obviously you have guest price guest limit uh the the the recipient of the transaction the value the call data and then three pieces of the signature of the transaction with aaa actually because a lot of that is is now the responsibility of the contract so the transaction itself becomes very simple you only have nons target which is the aaa contract and data that that's all right the rest is then up to the contract and specifically the contract sets guest price and guest limit and interesting to note for compatibility because again we are just using the existing contract framework so transaction a transactions will like technically come from a special entry point address and that is there's kind of the only the only purpose of that is just to like initiate a transactions and then um the rest like uh signature verification whatever you want to do you just do that with the call data that the transaction provides and also interesting to note obviously because you don't have these more extensive checks up front the base cost of the a transaction will be slightly lower than existing transactions so now the the second the protocol change is in two new op codes and the first one is in a simple one it's just a non-sub code until now you can't actually like during execution you can't actually access the nones of the transaction but that is required because you have to be able to sign over all fields of of a transaction and so um yeah that's more technical change the other one is more interesting pay gets this is i mean sam already introduced that right a pay gas basically is is the new way that a contract can say let me pay for this transaction obviously you can only call that if you are within an aaa transaction so and if it's actually a transaction that expects to be paid for by a contract and then um the contract gives it just the gas limit and the guest price and then it works just as normal transactions work today um pages also act as a checkpoint right because um any changes right for example the payment itself but then also if you want to update your internal whatever nons or something all of these like they are they're basically set in stone as soon as you call pay gas everything after can only revert back to pay gas and then uh basically uh this this is like a kind of obvious one an aaa transaction is only valid if it has been paid for right so so the contract that you call into us at some point has to pay pay guess otherwise the transaction is not valid and this can't count it can't be included um the last one is just this is just a quick note like we the biggest of code is is specified to be version so we can have like future versions for example so we can also specify erp-159 compatible um gas prices so now up now to the memphis rules like the the first one i hope i hope you you came away with the impression that like the actual um protocol changes are very very like succinct and and easy to reason about now the memphis rules and the question is why do we even need them for normal transactions you always have like very simple validity behavior right you check the signature once and if it's valid then it can only ever be invalid if another transaction from the same account like reduces the balance or increases the amount of something right and that means you can always just like reliably chain multiple transactions together and still be certain that they will all be like compatible and you can just execute them one after the other for aa transactions this is way more complex potentially if you don't do anything about it and the reason is that like um if a contract accessed any like any stage before before it made the decision if it wants to pay right um and this state changes then you just don't know what what what the validity of the transaction is it might be that even with the new state the contract will still wants to pay but it might be that the new state will lead the contract to not no longer like be able to be willing to pay for the transaction so anytime any state attached during execution changes a pending transaction could potentially become invalid and that is a problem for miners because miners now when they want to like assemble a new block they just don't know reliably that this is a pool of valley transactions just pick one after the other but like basically they yeah they would have to revalidate and then discard and this is this is this is an issue and as well notes in general are like vulnerable to so-called mempool wipes where you have like your mempool is just like your list of pending transactions and it can like with a potentially what could happen is that like a new block comes in that changes some state and all of a sudden like your whole name pool that only consists of a transactions is invalid all of a sudden all at once right and and you really don't want that because that introduces quite quite a few inefficiencies and thus obviously these are these are like only problems if you do it like the eave way if you don't have any protections but the lesson here is like miners and notes need a protection mechanism against like unpredictable transactions they can like change their validity whenever and there are two to two restrictions that we introduce the first one is an op code restriction uh it's a full slide but i'll just glance over it because the idea is pretty simple the idea is just you don't want aaa transactions to access any external state right the idea is they should only rely like before they decide to pay after they can do whatever as normal transactions will but before they they decide on on payment they are only supposed to look at their own internal state of the contract not look at the outside world and you just do that by having like a list of blocked up codes i don't i won't go through all of them but it's like the obvious ones like right you're not allowed to to look at the balance of other accounts not at their code not that state of other whatever right you're just not allowed to look at external state and this is not enforced by the protocol right you could still have a a transaction with that violates these rules like in a block that that's that's fine where it is enforced is at the individual nodes if you're running a node and it has a mempool where it stores pending transactions if the transaction like violates this rule and and and access excellent state you just don't keep the transaction around because it's it's unpredictable it could like change validity at any point you just don't keep it around and that way you know for certain like my transactions can only be invalidated if their own state changes and this is this is like this is the first first part of the two-part solution that is very important here and like later on we'll talk about how you can then like loosen these restrictions safely but but let's first talk about the second part second part is what we call a bytecode prefix so contract code obviously that's just like a bunch of bytecode and that gets executed when the contract is called and the idea is so what we do we want to achieve here we want to achieve that we have already achieved that you can only like look at your own state for validity but now what we want to do is we want to prevent other transactions from changing your state so it's basically only you can like you can only rely on your state and only you can change that state that is the goal and so how do we prevent other transactions from touching the state well guns well very simple right the the prefix that the beginning of the the beginning of the of the contract code just has to have this uh simple prefix which basically just you just ensure that the transaction came directly from this entry point which again this is like this special address from where all aaa transactions come and if it doesn't you just you you you're only accepting like east deposits so you just log a little recipient a receipt message i mean and then you just immediately return and that way like every contract that has this prefix like you know for sure that its state can only change via a transactions it cannot be modified from the outside and this is like really important because now if you basically if you just don't keep transactions to contracts that don't have this this prefix and you also follow this these restricted up codes then your mempool is basically safe right any a transactions you have in your manpool they are safe they can never misbehave they will always remain valid if you are a minor you can always just take one one after the other to include in your block all of these rules that you need that like all the invariants that you had with the normal transactions now also hold with aa transactions and um again extensibility you can add like multiple known safe prefixes and this is important because now what we want to talk about after we talked about these restrictive rules now we want to talk about how can we relax them what kind of additional features can we bring to aa safely so um the eip2938 that we've described so far uh is useful mostly for single tenant applications applications that are used at most by one person these extensions uh expand that to allow for more complex prefixes more more users using the apps they they take it from a very basic to a very full featured account abstraction implementation so the first extension we want to talk about is delegate calls from aaa so this is uh you see you have a library like safe and or or safe math and you want to call that from an a contract you do that with delegate call and this is safe to do but it's only safe if the call target exists so we introduce a new op code set indestructible which obviously disables self-destruct so this gives you libraries and upgradable smart contract wallets another really useful feature that we pretty much need is static calls into aaa so this gives you read-only access to an aaa contract now this would always be safe because a read-only call can't validate transactions but we can't currently differentiate between static contract contexts and read write contexts so we introduced a new op code is static which remains true if the returns true if the context is static so this helps you read things out like exchange rates or smart contract wallet balances from a contracts this is probably the most probably the second most useful extension to aaa which is read write calls into an aaa contract so the mempool wipe that anscard described earlier is probably the biggest problem with read write calls into aa a single transaction would be able to invalidate tons of aaa transactions and wipe nodes mempools we want to prevent that or at least make it safer and the way you do that is by preserving the amount of gas an attacker would have to spend to wipe those uh the ratio of the ratio of the amount of work that would have to be revalidated to the amount of gas spent on chain and the way we do that is by introducing a commit gas opcode this establishes a lower bound on the amount of gas the um aa contract will consume and it will be called by the a contract when it's invoked by a non-a transaction so this enables deposits erc223 tokens and surprisingly it allows an a contract to sponsor another a contract and we'll get into that a little bit more later this is probably the most important extension to 2938 which is multiple pending transactions so this lets you go from a single tenant application like a smart contract wallet to a multi-tenant application like a mixer or or an exchange this lets an aaa contract propagate more than one pending transaction so no in normal operation the nonce is chosen by the person who creates the transaction this with this extension the miner chooses the nonce for the transaction immediately before evm execution that lets the aaa contract choose its own replay protection and basically it can ignore the protocol nods the downside to this is that every time an a contract state chain changes all the pending transactions for the contract have to be revalidated this revalidation effort is bounded though on a per transaction gas limit and a per contract cumulative gas limit and again this enables very efficient multi-tenant applications so there's an interesting property about validation some parts of validation are pure meaning that they can never be invalidated normal ethereum transaction signatures are a great example of this um so are zk proofs once these pure validation portions are shown to be valid they can never be invalidated if we can cache the results of these validation steps we can enable significantly higher validation limits since you don't have to repeat the validation every time the way we enable this is by adding a new prefix where the aaa contract calls into itself and that creates a cash point where the evm can intercept this this call and cache the result of the pure validation now to make this a little bit more efficient or elegant we can introduce two new op codes pure call and is pure which detect perhaps obviously if the call is pure or not or we can just rely on mempool rules um we don't need a consensus change for this and what this gives us is a lot more gas for zk proofs building on top of that we can actually increase gas limits even further with this dynamic validation gas limit so well-behaved contracts can commit to a minimum gas spend and if they do that we can increase the amount of validation gas limit the limit can be increased safely because we maintain the same ratio of on-chain uh gas to revalidation work in if an attacker were to try to wipe mempools and this gives us even more gas for zk proofs and even more importantly more pending pen more pending transactions per contract we've also been working on a sponsored transactions eip that is complementary to aaa and sponsored transactions is where a sponsor pays the gas for another user unfortunately eip2711 is incompatible with aa um so we're just introducing a pre-compile that sets message.sender based on an ecdsa signature this lets you pay for gas and tokens which is pretty exciting i think so now we have like a summary slide and unfortunately we are running uh out of time so i i assume i think we should just skip it and directly go to the next one but if you're interested vitalik recently gave like a really great talk about account abstraction on a at a meet-up and there's a youtube link at the end of our slides that where you can go and listen to him i definitely recommend that and he talks about that extensively so just a quick summary of where we are right now in the eip so erp 2938 is a draft in the eip's repository i recommend checking it out there's a link at the end um we've had some light discussion on the all core devs meetings uh we want to move it to considered for inclusion soon where would join the pending uh the pool pending features that can be added to hard forks um we as in quilt are aiming to get this into the hard fork after berlin which is the next hard fork um but we're really not sure if this will ever ever arrive on maintenance but we're really hopeful it will and we hope people find it useful enough to include it and just as a like the last uh to tie into like the very first day of of these talks when if you remember vitalik talked extensively about like the roll-up vision for for well the yeah the roll-up centric vision for for e2 where basically these two becomes more of like a layer two uh management layer and most of the scalability actually comes from execution on these layer two solutions and so basically uh one question that we think is relevant not only for account abstraction but for features in general it's like do you want to keep extending the like the base chain with with all these additional features or is it like a better fit to just bring them to the roll-ups directly and we are deaf we are like very open to the possibility that aa will not ever make it to to ethereum because it's just like not a priority although at the same point there are def there are some synergies that you would also get like regarding layer 2 management with account abstraction and so we are still confident it it will uh provide and edit and like like value but this is definitely like a conversation that i think will be more important like going forward so we wanted to mention it but with that um yeah we want to hear from you um does account of abstraction make your dap use case easier could it um if it does what extensions do you need the most is there anything else you could use um and do you think this is something that you would love to have in mainnet um or do you hate it either way please contact us on the ethernet discord links here and also at the end um yeah so thank you very much and uh i think we have a few minutes for questions but i'm not sure wow uh that was a very extensive overview thanks so much um we do have some questions and there was also a lot of discussion already going on uh during your talk in the chat so also feel free to check that out later but i want to relay at least one or two questions to you guys now um the first one being around backwards compatibility which parts of account abstraction are backwards compatible and which ones are not so i think um what we tried is to basically have the changes be as minimal as possible and that includes um having backwards compatibility and so basically the idea is just existing contracts today um because this this new upcode this page's output is not yet in existence and so existing contacts just don't use it and so your existing contract will not be able to to to like ever upgrade to an aaa contract but what you can do is like existing libraries as we said can can still be used and so you there would definitely have to like be the need for like a one-time migration to a a contract if you want to use them but there's nothing that like would break or anything okay and then another question um would ecosystem infrastructure need to be updated or integrate some special considerations to benefit from account abstraction i would say yes um wallets are definitely going to have to change to support the new transaction type um you're going to have to introduce like block explorers are going to have to handle the new transaction type and they're also going to have to handle the ui of not exactly having a 2 and having a target instead transaction hash uniqueness is another big one so during eip2938 we do maintain transaction hash uniqueness all the way through so that one's a very minimal change but in some of the extensions transaction hash uniqueness changes a little bit and that'll require some work in the infrastructure as well okay and then last but not least um what is the difference between this and the gas station network so go ahead i was going to say so this is a very complementary to the gas station network instead of having external nodes relaying these transactions you could have a gas station network contract on chain that handles um some of the work for paying for these relay transactions okay amazing um yeah please do check out the chat because there's been a lot of discussion uh during the presentation but now due to time i will not relay all of the remaining questions and move over to our next
Automatic transcript — names and jargon may be misspelled.