ERC 1271 & ERC 6492: Signatures for Contract Wallets / Account Abstraction

ERC-1271: Standard Signature Validation Method for Contracts · 19 Apr 2023 · 41:26

Peter Robinson explains ERC-1271 and ERC-6492, standards that let smart contract wallets verify signatures the way externally owned accounts do, including for wallets that haven't been deployed on-chain yet. The talk covers why standardized signature verification matters as account abstraction moves more users onto smart contract wallets.

Speakers

Topics

From ERC-1271: Standard Signature Validation Method for Contracts, hosted by Ethereum Engineering Group.

Transcript

hello and welcome everyone my name is Peter Robinson today um at the ethereum Engineering Group Meetup I'm going to talk about [Music] eip1271 so it's about signatures and contracts about account abstraction so who am I um so I'm um Peter I work as the head of blockchain research at a company called immutable which is developing a games platform has some games as well and it's all all about web 3 games and game five um so without further Ado let's um just kind of mute that yep I'll just

share my screen just a sec okay can people see my slides okay brilliant right I'm just gonna get that out of the way okay so as I was saying um let's talk about um erc1271 so I got some feedback from Philip so thank you a lot from Phillip who's from Horizon games so we're going to talk about the ERC and the usage of it and how you you know go about using it and then talk about the standard and talk about what it isn't

because I think there's a lot of confusion about what this um this is all about um we're going to talk about the flexible signatures and what it actually means and then um you know account abstraction is pretty hot so let's talk about that as well and how this all interrelates and we'll talk about catafactual wallets and ERC 6492 which is a new one and like is this actually used you know after I'm been talking about it for all this time so let's keep on going so is it an ERC or an EIP so um if you go and look at EIP one it tells you all the different types of

things and so an EIP that's actually an ERC is one that's an application Level standard and so this is about smart contracts and applications so it's an ERC not an EIP that you'll often see it down as eip1271 so normally when you've got um what wallet contracts the idea is you've got a human and um you know they're using some wallet Library where they write that the function calls that they want to execute to the transactions and the idea is that they pass this off to the relayer servers

and the relayer service actually submits the transactions for them they personally do not have to worry about nonses and all that that's really down to the relayer server so they don't have to pay they're not paying for gas directly and then um the wallet contract then does stuff executes the transactions and then you've got application contracts that you know are the receiver of those transactions of those function calls and so that's you know normally how you do things with um contract wallets and so what you often have though is a situation where you want to prove that

you're the owner of an account um what you might have happened then is you'd have all right look I've got this account and then the application says do you really have that account are you really that oh that person or that account holder and so they'll send you a challenge and that challenge could be a random number and then you send back a signed response back to the application and so you sign that with your um with your wallet and so essentially you've got some part of it that is off chain and you're signing with the off chain part and then the validation of that signature happens

with the on-chain part so the actual wallet so then the app then talks to that wallet and says is this a valid signature that I've just been given and so you could imagine say say I think some of us have used decentral land and so into Central land you've got some nfts and the nft say represents a hoodie or you know some article of clothing before you can access that you have to say well I'm this account and one of the first things that um the decentraland application at the game wants you to do is prove that you're that account holder so if you've got an eoa it's just a matter of signing signing a challenge

but if you're not a neo8 and you've got a contract wallet this would be how you would do it another thing you could do is you could have a signed message so you want to do some off-chain message that you um use for something say a an auction or something and so you submit an off-chain message that you've signed and then the application it really needs to check that that signed message is valid before it you know say lodges your bid in an auction or something like that so it's going to go is valid signature and then later on say you win the auction then it's going to submit the signed message

to some application and then that application is then going to go is valid signature to you know check to see if it's a valid signature or not and so doing that just um yeah so doing that then um means that you know you're on chain the application is able to check and then assuming that that message has been signed and you know you've got that wedding bid then maybe you know you get the article that you've bid for um so the you know of course the messages can be anything and an important thing to think about is that

unlike say ethereum transactions they might they're not going to necessarily have nonsense you know they could have a knots but it doesn't have to that's going to be down to the wallet and the application so you could have a message that could sit around for a very long time and not have to be used immediately and be used out of order okay so what is the standard thing so um it's a standard way of verifying signatures when the account is a smart contract and so the idea is that so eoas have got private keys that contracts don't so it's a way that you can have um an API that can be called to verify a

signature and so you can have is valid signature hash signature and so looking at that the idea is that the contract wallet has this API where you pass in the hash of the message that you're trying to sign and then you've got us you pass in the signature and then you're going to return a magic value and the magic value happens to be the function selector for is valid signature and if it's true otherwise you'll return some other value if it if the signature verification fails for some reason and so the hash relates to that data and that data is application specific

but the signature is wallet specific so if you're the if you're building your own wallet you get to choose what's in that signature and work out how you're going to verify that signature and as I said that fancy number there is just the function selector for the function and so I know I looked at that and thought what why aren't they returning a Boolean but you know valid or not valid and the in this in the EIP it says the specific return value is expected to be returned instead of a Boolean in order to have stricter and simpler verification of a signature

so I don't know if you have a look at the the first set of code and then you have a look at the second set of code where I've said well what happens if you return to Boolean and to me the second bit of code looks easier and simpler and it's going to be cost less gas as well but anyway so that's the standard so I don't know maybe you could bang in some extra error codes into that bytes for later but an enum would have been a better option so yeah I don't know why that that doesn't make sense to me but anyway it is what it is the ERC isn't about say I'm using it for contract level authentication so say

you've got required message sender is some authorized party it's not a replacement for that you would use message sender in that case so if you're looking you know has the wallet you know is it is it the wallet calling me um it's also not going to replace say when you're using say message sender in the context of say an address map or anything else where you're using addresses so it's not used in that context it's just for do I own the account and can I sign off-chain messages that are later used on chain um so what about

um you know how does this all work then with the account abstraction and the you know flexible signature verification so um so having a contract signature opens up many possibilities um though um you know the thing of course is that you're doing this verification within the EVN though and you've got to think that that is valid signature is called by other contracts so you can't have it using millions of gas if at all possible um normally you know like we've got the eoa so not um signature verification you've got one signer and you've got a one specific curve that you've got to

use um whereas you know if you're using this standard or what contract wallets generally you could have multiple eoas um signing for um you know to sign for the wallet so you could have you know require that every single eoa signs and um yeah so you could have each eoa signed separately and they then put it into the wallet and then if not if all of them have signed then the actual um message gets executed you could have a threshold number of signers so you could say all right we're going to have three of five you could have waiting as well so you could say well this particular signer is

what has the weight of three and these other signers only have a weight of one and so you know three of those have to sign to be equivalent to that other signer um but you can also have changing validity which is an interesting one so imagine you've got one of those multi-sig techniques we've just talked about so you could have use array and user B could sign and so you could return is valid is true then you could remove user B from the multi-sig and add user scene and then when you then next go to validate that same signature is valid signature is going to return false and so you know obviously you could put

in logic to honor the historic signature but um just you know using a simplistic scheme you would fail the signature verification um obviously with contract wallets it also means that you can do other things you could use BLS or entry or some other scheme where you're not going to use up too much gas because you've got to remember you're trying to verify those signatures within the evm um you could have mentioned you could have expiring signatures so you could say well look I'm going to sign this message but I want to have um I I you know I don't care what the

application says I'm expiring this signature within 24 hours and so you know then that again means that a signature might be valid at one time but later on it might not be valid um yeah obviously though when you're doing this sort of scheme um the time is going to have to be part of the hash that you then sign so in other words what you do is you have the data hash supplied to you and then you would have the expiry time and that data hash that you would rehash and then sign the overall hash because otherwise anyone could arbitrarily just modify the expiry time um so you could also have a unique ID

per signature and so what you could do then is you could disable specific signatures so you could decide that you you know you you don't like that particular transaction so you want to revoke it and so you could you know have given an ID and say it's id17 then after some time you could invalidate that signature which again would mean is valid signature returns false thank you could also Imagine doing something a bit silly where off chain you return true um but if it you get the same request on chain then you return false and so if thinking of this scenario where you had

an off-chain message that the application checks to be correct you return true but then save was an option you could put in an infinite bid knowing that when you actually get around to executing um you know step four it's going to fail um yeah you can do all sorts of Nefarious things um another thing to think about is that so even if you've ordered the wallet implementation code and you fully understand how it works most of them are designed as proxies so it can upgrade to a new version of code so um you know there is that possibility that even if you start out with something good

um a type of signature which is revocable in some way could occur so really then I think when we look at the standard and those last few words there you know whether a signature verify whether a signature on behalf of a given contract is valid or it should be is valid at a certain point of time and given a certain state so it's really is the signature valid Now is really that what the API should be and in fact what um opens apple and have used so when we think of normal signatures um you know normal digital signatures

um you've got authentication properties and non-repudiation so authentication is um saying I am you know I'm the one who signed and non-repudiation is you can't get out of an action and so the eoa signatures definitely give you both once you've signed you know you can't really get out of it you could I guess you could claim that someone has compromised your private key but beyond that it's really impossible to say you didn't sign but with the one two seven one signatures you've definitely got authentication but the non-repudiation it really does depend and a big question should come then so

for the intended use cases does this really matter and so all right so authentication I'm the owner of this account those nfts that are in part that are associated with my account can be used by me in the game and so you know the example being the nft T-shirt born by my character in The metaverse so you know authentication it all works that's all good and again if we think I'm the owner of this account I've got the right to transact because I own that informational those tokens and so again you'd be you'd have your bid accepted so that would be all good

um non-repudiation which you know was preventing you denying that you'd done something or you'd sign some message um so I want to do an action say buy something at a certain price and then I change my mind because actually I don't like um the prices fall and so I'm not interested anymore and so um non-repudiation should lock you in so you can't say I don't want to do it anymore um and so that's the property that we're not quite got with this um in all scenarios so um yeah and as I'm saying here so the non lack of non-repudiation means that

the winning bidder can make the transaction to do the final transfer fail whereas if you're on eoa you couldn't do that it would go through okay so what about account abstraction so account abstraction is really um just contract wallets really when it comes down to it and so not all contract wallets need erc1271 so if say your use case um you know use cases don't require um the use cases that are covered by er1271 like proof of who owns what wallet or

um signing off-chain messages then you don't need it however you know I would have thought if I was going to be implementing account abstraction from scratch I could imagine putting it in simply because it's a feature that some people will want because that whole proof of ownership business seems to be pretty fundamental I think so how to factual wallets and ERC 1692 so a counterfactual um is you know Sox means expressing something um that hasn't happened or won't happen um so isn't the case so

um in the case of a counter factual wallet the idea is you give a user an address an account but you don't deploy the wallet until they need it so you can so it's it so that using that word counterfactual meaning you haven't actually deployed the wallet yet or you know the wallet doesn't exist yet and so um yeah that that's what it's meant by a catafactual wallet and so create a kind of factual wallet you need to know the address that it's going to have before you deploy it and so you use create two to have a deterministic contract address and so the um the create two uses the

address of the deploying contract uh salt and the creation code for the proxy contract that you're going to create and so you can imagine a simplistic flow that looks like this where you've got a relayer that deploys a wallet Factory that creates the wallet the wallet proxy and then you say execute some function call um and it does a delegate calling to some wallet implementation so that all looks fine um but what happens if I call this valid signature before the wallet proxy has been deployed

so at the moment that's just going to fail because the contract doesn't exist and um you know but you can imagine that would be a really bad UI um because you know say if you've got some game and you've given a character a user um you know I don't know an ax or whatever some some implement they might not have done a transaction I mean chances are they haven't um they might only need to do transactions later in the gameplay if at all and so you don't want to have to deploy contracts for everyone so you need to be able to handle the fact that the user does not have a contract

deployed here erc6492 aims to cover this situation and so when you sign so if the contract has been deployed you just use normal erc1271 but if it hasn't been deployed then you um you end up having the address of the um Factory that you're going to use the call data that you're going to pass into the factory including um the which is going to include the bytes to be deployed or something you know some information that you're going to call and then also the original signature so the actual

erc1271 plus some magic bytes um that you you've got that are defined in the standard and so we've got the Factory address the or Factory address the call data that we're passing into the factory to get the contract deployed which is going to include the salt and then the signature under verification side so if the signature ends in those magic bytes which indicates hey this signature was generated before the contract was deployed then rather than doing a transaction you do an eth call so a view call and what you do is you call the factory with that factory call data to

get the contract deployed and then what you do is you call is valid signature so because you're doing all of this in the context of an eighth call the um you know the the distributed database which is the blockchain so the distributed Ledger doesn't get updated it's only the copy of that that you've got temporarily whilst you're executing this function to verify the signature um yeah so if that's not the case then I'll you use erc1271 if the contract code's already been deployed and if there is no contract then you use EC recover because you assume it's an eoa so um yeah so again highlighting because

you're calling if call it's just a view call you're not actually going to update the blockchain but you are going to in your temporary version of the blockchain deploy the wallet and then call is valid signature on that temporarily deployed wallet so who implements um this standard um is it is does anyone so there are at least three wallets that implement it gnosis sequence and Argent um there are some libraries out there that um help you implement it or do implement it and as well there are some products that um implemented as well so there's a range of um of users and I

imagine as a um account abstraction becomes popular um the rate you know pretty much everyone will move to using this for you know those situations of proof that you have the account or are the owner of the account and signing off chain messages so in summary um this EIP or ERC really gives you a way of proofing ownership of an account and doing off-chain messages um most account abstraction wallets are going to need to implement this you can have a multitude of signature

schemes but um signatures are only definitively valid at a certain point in time so they can expire or the configuration can change and um there are a whole stack of forthcoming talks um pretty much one a week in May um and um yeah lots of interesting talks and you can engage with the community watch us on YouTube or join the meetups so let's stop sharing and look at the um questions okay all right

Hayden I have a question for you oh Hayden's got his hand up there you go he's going I want to answer a question um so Hayden my question to you was what changes natively support account abstraction uh as far as I know it's just CK sync and um the the other one sorry with its own language oh okay yep I'm stuck where so stuck X or something yes yeah um so I actually had a question um so you mentioned the nefarious signatures that verify off-chain but not on chain are there any potential mitigations for that

um I don't think so I think I think how you can think of this is um you can think of this as a um a new type of signature and um you can think of it as well like I mean you could if if I had an account say if I was an eoa um and I did a winning bid for something I could then move money out of my address into you know move all my eth out of my address so then when the actual transfer goes through is for me to buy the nft it's going to fail anyway so it's probably not as bad as it sounds um if that makes sense that you know

like you could still fail you know like agree to do something and then fail it anyway because it's due to insufficient funds at the moment and there's very little you know legal recourse that you could have right thank you so I have a question Peter is valid signature that's something you can write as you wish yeah yeah you're writing your wallet so you can sign your own um it doesn't have to satisfy some properties being

securely well semantically secure or whatever or no you could return true or return false yeah okay okay um so does it uh because then it's somehow allows users or developers or smart contracts to write their own recipe Source signatures yeah it's true but I think um in normally underneath I think you're going to see that there's just you know it's normally just a multi-sick wallet where you've got say two different signers and it's just doing EC recover or something like that I don't think many people you know I think people are

generally going to write their own signature scheme and even writing a multi-sec while it's non-trivial I reckon you can put as much information as possible for the it's more it's more for the user because user is signing it so user would like to know what information they signing a good example is the one inch fusion fusion order they let you sign a really long message in in your metamask you will see the prompt of what asset what taker assets swap to what maker asset uh expiration like 10 minutes and then at what minimum

price all the information and then you sign and then they can allowing the contract to take your money to do the swap so I think it's it's more a UI thing that you want your user to know what you're signing so I think in that case isn't that all data from the application as opposed to wallet stuff or yeah because this is this is slightly separate this is you in the wallet itself saying I mean because I can imagine applications having timeouts make sense you know you don't want a message

hanging around forever well I've got a second question I guess now you can't abstraction concept it's not uh let's say ethereum specific right it could be applied on other chains running something different to an evm the specification that you presented and I think it's not you but most of the specifications are written in solidity but it's probably something that could be defined at the evm level or I don't know but writing it in at the solidity level doesn't seem right to me because it's uh it's not the semantics of of the machine that you're running on so is

there something uh let's say more abstract to read about how it's defined in a more let's say a rigorous way that rather than solidity uh this is just the interface it's just it's just the internet interface okay okay so yeah okay and even if you read the language which you know I know you you and even for myself I I look at it and I think oh that language is a bit loose you know and that's you know just the verbiage around it um you know exactly the you have to have the signature the the four bytes of the kitchen and so on in your uh contract to be compatible or compliant yeah so again it's really very illegal okay um that it's locking you down to me I I

read it and I think ah golly it's a standard no one I don't know standards are a negotiation between lots of different people with lots of different interests so you you achieve you arrive at something that no one's really happy with but everyone can sort of agree on um so then there's something I also was curious about stop weddings on the defensive side I wouldn't like users to be able to think that they can they can write their own uh signature scheme so I would provide some predefined schemes for instance and could it be defined as pre-compiled or things like that or is it something fantastic

I so I will admit I've looked at the sequence code a great deal I have not looked at the gnosis or Argent code in detail because you know you could well find a deci gnosis has been around the longest and it would be really interesting to look at the gnosis code and see whether the signature scheme that is used by gnosis is the same or very similar to what is used by sequence and Argent or or more to the point whether the two of them have inherited the format that gnosis of use but at the end of the day though they don't need to be interoperable because you generate a signature using your library and the

only thing that can verify that signature is the contract on chain so it's really up to you to write your library and your contract yeah and the other thing as well Frank is I don't think even it's open source software and it's you know I would have thought people will generally look at one of these um the wallets and just copy the code or you know use the code rather than um inventing their very own wallet yeah so I agree but um I'm not an expert in crypto but what I learned is that you shouldn't try to cook your own signature

scheme or Mac scheme or whatever you should use standardized ones so I'm a bit worried about this this opportunity to write your own signature scheme oh yeah I mean it's like the the bit where I said about fee including the timestamp um you know you could easily muck that up to have a very good secure signature scheme and make it you know very very insecure by mistake just by doing some incorrect formatting and um yeah there you go um so I did have a question um what physical form do private Keys

take in these systems of off-chain Wallops UB keys or something else really good question so some people do have Hardware wallets um some people have in-memory stuff so metamask but metamask can use wallets as well um or Hardware wallets some people will um hsms in the cloud so in AWS or Microsoft azure so I think that there's a wide variety um and Hayden I can see you've got your hand up yes what implications does this have for non-atomic transactions like say a cross

chain non-atomic cross Chain Bridge yeah do you see anything there yeah you wouldn't want to I mean having something that can be signed that is then unsigned um is not going to work but yes I guess you would have to be careful about any scenario where there you weren't going to immediately action so a non-atomic or a bridge where there was more than one action but I guess the thing is that that contract wallet only works on a certain chain so you could I guess potentially

deploy the same wallet on a different chain and um I guess assuming that the other chain supports the same semantics you should end up with the same address assuming that the factory was deployed to the same address so um I guess you could verify the signature on multiple chains assuming you know you could deploy it to the same address so um yeah so but I think yeah any anywhere anytime when you're going to have the verifying at different times to when you're signing it's going to be messy so that means that for Roll-Ups for

instance it could be an issue they have to have the context and replayable transactions in the similar context and yeah um sorry Frank go ahead say that again please well in a roll-up let's say with the fraud proof or whatever you have sometimes to replay the transaction so you need to save the context of the the transaction on the L2 to be able to replay it so that's something they can do but that could be something as well that we'll have to do but the but to invalidate the transaction the user has to do a transaction to update state on chain which is that means they've got

to get a transaction in and so even if you're replaying as long as you're replaying them in order it shouldn't matter because they can't put a new transaction in in the middle I have a question would you be able to expand on why non-repidiation does not hold for the erc1271 uh yeah sure so it doesn't always hold so in fact I dare say all of the wallets that are available today I don't as far as I could see none of them supported having time-based repeat you know like

timeouts of signatures but if a contract wallet did then the fact that you can go from having signed something and it then is valid signature returning true to later caught having is valid signature returning false um that allows you to repudiate stuff so you know you can sign something and then later on you can say no I didn't sign that and you try and verify it so that's why non-repudiation doesn't you can potentially write the wallet but you can you can write a wallet well

at all yeah and in fact all of the wallets that I think are available today as far as I know um non-repudiation holds for um but then the what I said about upgradable wallets all of that applies yeah so that that's um definitely something so the fact that all you know they're all proxies with implementations you can upgrade to a new implementation and when you do that then potentially um you know the um the implementation could allow for revoking signatures

obviously though you've got to put the information in the signature in the first place you know so you've got off-chain code and you've got to work out a way of you know like putting something in so you'd know whether you wanted to revoke a signature or not because it's got to be in that signature blob are there any other questions I think we're all out okay well thank you very much everyone and um see you in about two weeks time um have a great day bye-bye thanks Peter

for a great presentation