[trustless://interop.landscape] Workshop - Hidden Contract Accounts: Interop through ENS Namechain

trustless:// at Devconnect Argentina 2025 · November 2025 · 36:16

ENS Labs protocol engineer taytems.eth and developer relations engineer Greg Skril explain Hidden Contract Accounts in ENS Namechain. The workshop covers deterministic deployment with CREATE2, human-readable authorization and ERC-7579 session interactions, alongside DAO-controlled upgrades and asset ownership across multiple networks.

Speakers

Topics

From trustless:// at Devconnect Argentina 2025, hosted by Account and Chain Abstraction.

Transcript

Okay. Can you guys hear me now? Great. Cool. So, hey everyone. I am Greg from ENS. Um, and we have Tate here as well. Today we're going to be talking about interoperability in ENS v2. Um, but before we talk about V2, is this working? Nice. Before we talk about V2, I want to take a step back and talk about what is ENS in case um some of you guys don't already know this. So the Ethereum name service is a decentralized permissionless naming protocol that lives on Ethereum mainet very specifically. And the most basic level is that we turn complex hex addresses into human readable names. Right? So

instead of typing ox179A so on into a wallet, I can type Greg.eth And that is my onchain identity. You know, that is a pointer to my wallet. Um, and this just sounds like a username, you know, a name to an address, but really over time it's become more of a profile. And so this is a look of my ENS profile. I do have the address as you can see, but I also have a description that I like baking and building apps on web3 protocols and an avatar image and all these other social protocols. Um, and addresses on other chains as well, EVM and not. And so this is kind of what becomes my portable web 3 profile.

Another look at how you might see this in an app. On one hand, you connect to an app and it shows you your address. You know, this doesn't mean anything. A web two user that's coming into crypto sees just a random string of numbers and letters and this is meaningless. It's not personable at all. Whereas with ENS, you have a more personable connection into your app. You sign in and you have a name. You have an avatar. this feels like my account, you know, my portable web 3 profile. And not to be like shilly, but ENS has been around for a while. Um, there are over a million active.ames and hundreds of integrations. All of this is to say that, you know, it's worked pretty well so far. But in order to scale to what we want it to be and for the average user

to be able to use ENS and register a name um without kind of understanding all of crypto, we need to improve. And so if you have registered a dirty theme in the past, you may have seen a screen like this. And there's a lot going on. So let's kind of point out a few things. Um first is that there are three steps. And these three steps take at least a minute to complete, which is kind of slow. You know, users aren't used to waiting a minute just to do something in an app these days. Next, you'll notice that when I took the screenshot this morning, gas fees were over 10% of the actual fee of the name.

And when you think of it in percentages, this is just kind of crazy for normal users. You know, web two users are not used to this. Um, we kind of talk badly about credit card transaction fees and those are significantly less. And again, this is on a good day. There are times where the transaction fee is multiples of the actual fee. Um, and speaking of the fee, it always has to be paid with ETH on Ethereum mainet on L1, which it is increasingly unsafe to assume that the average user has ETH on L1. And so these are kind of some of the problems that we see and that we seek to solve in uh the next version of ENS. But just a funny way to think about this is that ENS sees itself as a user experience protocol. You know, it tries to make crypto easier to use for users, but

actually our own user experience isn't the best. And so like the experience of registering a name and so this whole upgrade of ENSB2 is trying to improve the UX of ENS so that we can better serve the whole ecosystem as user experience protocol. Um yeah and so what does making registration easier look like? It looks like some of these things. A user should be able to register a name quickly starting on any chain starting with any token in less than two wallet interactions which we have today. So obviously we don't want to make it worse. They should be able to use any wallet. They should be able to use any client, meaning any website should be able to implement uh this stack that we're about to talk about. It should be

completely permissionless and as trustless as possible. So these are kind of the requirements that we have in building out um NSV2 on namechain. And this basically makes obvious that ENS needs some sort of account abstraction. You know, you need account abstraction, you need chain abstraction, all these things. But actually when you look at the current stack of account abstraction, it becomes clear that the exact pieces don't solve all of our problems together. And so we have to come up with uh a little bit of an innovation on top of the existing stack.

And so that's what I'm going to bring Tate on to talk about. Hey guys. Um so uh about account abstraction on on namechain. The current account abstraction options are essentially between uh two sectors. We've got wallet based and appbased account abstraction. Um on the wallet side we've got 7702 or a straight SCA implementation with um like a pass key signer or something. And uh on the app side that tends to be just um standard SCAS.

So um with wallet based account abstraction, our issue generally is that it requires a specific wallet. Um 7702 is a great specification. However, uh many wallets unfortunately do not implement 7702 and as such we can't give the benefits of 7702 to every single user like all of the account abstraction stack. Um and that's a significant problem for ENS because we want to reach as wide an audience as we possibly can.

We want to be uh globally inclusive and even if the the biggest wallets support us support 7702, that is not 100%. Um it's never going to be 100% in terms of getting an ideal flow, but we'd much rather be on the higher end of maybe 90% or more. Yep. Um, so app based account abstraction is is the the other main option, but it's only the app that can touch the assets if you're using this method. Um, the the issue with that is that we don't

have any freedom for the user built in to do whatever they want to do. Migrate to a a different wallet. um use the functionality of names through a different system etc. Um or if you don't want to have the app uh solely authorized for um anything then you need explicit authorization from the user which is an additional wallet interaction. Um, and as Greg was mentioning before, one of our requirements is that we want to keep it to two wallet interactions or less for registration. Um, and for any other

uh interaction on ENS um then the alternative to both of those things is having some sort of lookup system um that every application can implement. Um so to outline a specification of what we really want is account abstraction but you can use any wallet. You can access it with any supported app or if you have an unsupported app it should still work via users wallet and on both Ethereum and uh mainet and namechain.

That is another crucial step in that we can't have a chain native solution because in SV2 spans multiple chains um not just a single chain and we don't have um well we have a say but we don't have any control over what happens on Ethereum name mainet um so what we're creating are hidden contracts contract accounts or HCAS as as we're calling them and essentially it is just a dedicated SCA or a smart contract account implementation but with a lookup mechanism built in. Um >> okay uh the lookup is really just a

mapping um and that mapping is really dead simple. This is nothing insane. This is not some crazy new architectural decision that we've decided to make. It's a simple mapping and uh it enables the benefits that we want to get for SCAS for every user um like basic multi call gas sponsorship um and everything that's beyond that that hasn't been discovered with modular accounts as well as what I'll go into detail um in a sec about in browser burn

assigners which is allowing us to keep our wallet interaction limit very low and in some cases even be able to achieve a full registration process in a single wallet interaction which is really nice. Um, so the the lookup is just on an HCA factory contract and it's so it's just one HCA factory contract and it recognizes a single implementation and it can maintain a mapping of a HCA HCA address to an account so that you can do a reverse lookup whenever you need authentication for anything. For example, if you are checking for um

ownership authorization, then you can use your HCA and the ownership authorization checking uh message sender will then use this lookup using the HCA address and resolve it to the main account where it will then be authorized to do exactly the same thing that the main account would be able to do without any extra steps beyond that. and is very simple to implement. Um, so on the implementation, we've uh chosen to go with open Zeppelin's pre-existing context pattern which establishes uh message sender function that you should call in instead of message sender

whenever you're using a uh solidity um function. and we're just replacing it with HCA context which I'll show you in a second and it's a very simple implementation but for a developer who wants to utilize HCAS this is literally all that you need to do from a contract side to be able to recognize HCA and then once you're part of that ecosystem you get all of the same benefits that all of our protocol contracts are going to get as well so that's not something that I included here but all of protocol contracts will recognize HCAS just as they would recognize accounts. And so you just need to initialize it with HCA

equivalents which again I'll show you in a second. Um so let's look at some code. Let me just enlarge this a little bit. So we've got the HCA equivalence function and it's uh the message sender underlying implementation. All it's all it's doing here um is we're just checking for a factory address and then we're going to do a lookup on the factory for an account owner from the HCA address if it is an HCA address and assuming that there's no insane um hash overlap that that will

just return zero if there is no main account aka if it is an HCA if it is not an HCA A um and so we're just going to return the message sender. Otherwise, we're going to return the account owner instead of the HCA. And so then all of your ownership checks, all of your permission checks. Uh if you're familiar with ENS nameus would theoretically use um this lookup instead of any um custom authorization logic on top.

and we're implementing it in HCA context itself uh just like this. So all we're doing is we're just replacing so this is the uh open zeppelin context uh contract and it just defines a message sender function and we're just replacing it with a call to our HDA equivalents and that's all it is. It's it's dead simple. But um that's the implementation. As for the code itself, uh the SCA itself, uh we've got someone from Rhinestone here who can take you through a video of a demo. I believe

>> quickly that take from there. >> Yep. >> Good. Can you guys hear me now? Nice. Um, thanks for coming, guys. I'm Conrad. I'm from Rhinestone. Been working with uh the guys at DNS. Um, so yeah, essentially kind of continuing on from what Tate was talking about with the HCAS. I wanted to show a quick demo in terms of what the whole experience looks like. Obviously, this is just kind of like a demo app and not kind of like final UI. But I guess I'll walk you guys through um the whole experience of kind of using the HCAS but also kind of

seamlessly going crosschain. So starting on Solia and going to base Sipoleia in the future that will obviously be kind of the ENS name chain. Um but yeah, I guess let me get started with the demo. So obviously here we just have some demo UI. Um is this full screen? Does >> that work? Okay, never mind. Um, >> never mind. >> Anyways, um, so this is the demo. Um, you kind of connect the wallet. You can just connect any any EOA that the user has. And I guess the important part here for the demo is, um, yeah, just showing that we have some USC on. And then pausing here quickly, it spins up um, an

HCA as you can see here on baseia, which in the future will be on namechain. And the idea is that this HCA um I think I'll show show that in a second on the explorer doesn't have any funds. It's not really deployed yet. It's kind of just like the user comes with the EOA, doesn't have anything else. And so like no balance on uh basically in this case a namechain in the future. And then the idea is that the user wants to be able to go from their existing funds whether that's USDC, ETH or any other token to namechain and buy the domain that they want both atomically and quickly and also without needing to worry about bridging. Um the idea as well is that it doesn't kind of have to be Zapoleia or mainet. It can be kind of any other chain that the user can move from to

name chain. So entering some domain here uh which is available and as you can see here the user doesn't have any USC balance on uh basipoleia um but it has balance on on like normal cipolia so under the hood when the user does the ENS like registration process which is what was mentioned earlier it will also atomically bridge and kind of do that in one go. So that's the commit process and as you can see here the user just has to sign a message which is actually a permit to message. So anyone that has used like D5 before like unis swap for example um you will have like dealt with um permit 2 before and that allows you to spend your

tokens um kind of just with a signature instead of needing to actually make a transaction. And actually going back a second, you can also see here uh like here in the bottom left um that the payment token is USDC. So the user doesn't need to have like ETH necessarily and like I said before and and I think as Greg mentioned earlier that could be any token in the future like the user can literally just rock up with the latest shitcoin and pay both for the fee for the ENS and uh for the ENS domain and for gas kind of with that token. Um so going back the user will just um sign the permit 2 message and then the transaction will first happen on Solia and then kind of on base Solia in this case because Solia is pretty

slow like the block times are like 12 seconds on average um it takes a second but depending on the chain you're coming from this will be faster and also when it's on mainet it'll be quite a bit faster. Um and as you can see here so far there's just been a single interaction that the user has signed. Um so when this transaction has gone through on on the destination chain you can see that the commit which is the first part of the ENS domain um registration process has gone through um on baseia and as part of that um obviously the user has paid the fee as you can see here in in in USDC um and once again kind of as I mentioned earlier there was no USDC no gas tokens nothing that the user had on the target chain so it's a proper kind of app chain

experience where user can just go from funds they anywhere and just interact with this new chain that they don't even necessarily know about and kind of showing the user account again. This is now a deployed HCA um that has some tokens as well. So then kind of the second process is the actual kind of reveal or the registration step. And as you could see here, there's no wallet pop-up anymore because this is all handled by the local session signer. that's kind of the signer of the HCA on the target chain. So the user just press register and it it pretty much instantly goes through because like the app chain in this case Bolia is just super quick.

Um and then yeah just showing that you can see here that the ERC721 got minted which is the user's uh domain and that's pretty much it. Um, one thing that um, is also kind of like very easily possible with this is if the user wants to do multiple domains, they can also do everything in one kind of interaction, kind of bridge enough funds to actually register multiple domains. So, they don't have to even go through that oneclick experience. Um, but yeah, that's kind of like the the experience as you guys saw like the user didn't have any funds on the destination chain and it was just a simple one-click experience. um yeah that abstracts away a that the user even gets a smart account but also that they're actually

interacting with another chain. Obviously in this demo this was kind of like shown quite well but I think and the the the people at ENS have been working on on great there where actually a user interacts with an app on an app chain but doesn't even know about that because they never have to think about bridging. They never have to like actually realize that there is another chain involved. they just think this is these are the tokens I have on whatever chain and everything is super smooth instant I can pick ass in whatever token um so yeah that's kind of the final experience we're going for and super excited to see this live in prod >> um so

now that we've had that demo I thought might as well take you through a little bit of the protocol code as as well as um like at the implementation in the protocol. This is the namechain repo. Um so some of these contracts will just be on namechain, but a lot of them will be deployed across both namechain and L1. A little bit confusing, but bear with me. Uh so we've got an ERC 1155 token contract and this is pretty much a standard 1155 contract except we've just got uh an additional owner of function for ENS compatibility.

Uh so all I'm going to do is search for the cont. So, we've got HCA context here, and we're just inheriting HCA context, which is what I was showing before. And that is literally the only thing we have to do besides a Do I actually have it here? All right, it's on the registry itself.

All I have to do is search for equivalents. So this is a uh contract that's inheriting that 1155 contract and it's just got an initialization of the HCA equivalence which is if I can click through just our uh containing our function from before and it's got a reference to the HCA factory. There's only one HCA factory and that is the only thing that's required because we're already using the message sender helper here instead of message sender. So anywhere that we use message sender, it's going to be able to

uh detect and replace an HCA address with a standard address. Um, and yeah, so it's it's completely that easy. There is nothing else to it. And I'll continue on. I've got a few extra things to say here. Um, so we've got the in browser burner signers and that's what's removing those extra wallet interactions. Uh, we've got an issue with the in browser burner signers in that users will just sign things. they don't understand occasionally. Um, and if the brow the browser signers have unlimited permission,

then uh that can be potentially very dangerous at the ENS protocol level. This is sort of equivalent to like a 7702. not exactly the same, but the uh potential scope you could have in authorizing an in browser burner assigner is the same as a delegation on 7702. Uh so we're reducing it in scope to reduce danger. As well as that, the burners all have expireies so that they don't um leak or if you get compromised or something from a data breach a long

time ago, etc. That's nothing to worry about. It's all stored locally though in browser. It's never going to leave your browser. At least our implementation won't leave your leave your browser. um it's up to an app to make sure that that uh is the case rather than a wallet in some other cases. So for execution you can use intents but you can still utilize 4337. Intents are crucial for user understanding and you can execute them with unrelated data uh from the SCA or HCA implementation itself. But as a fallback, 4337 which is extremely widely supported is still there in the case that you urgently need to execute

something or if you have specific infrastructure that you want to run in a a different way outside of the intense framework. Um you have the ability to do that. As for upgradability, we can only have one current implementation, but users can be on older versions. So, we'll have just a a standard um set of versions from one all the way forward. And those versions can all be utilized by a user at the same time. Not one user, but many users.

Um so we can't uh restrict just to one implementation or we don't want to restrict to just one implementation because users should have the option in case of a malicious DAO activity um to maintain their SCA as is on the current implementation or if they just don't feel the need to upgrade they don't need to upgrade um and the DAO is the only authority that can authorize updating the current implementation to newer versions. Um the the reason we have to have one specific version is again because of safety. uh

we don't want a user to be able to assign arbitrary uh full access to uh the ins protocol on behalf of their account because like before it's similar in scope to 7702. It's pretty much just a delegation and delegating is dangerous. Most wallets won't let you delegate to or all wallets essentially won't let you delegate to a generic 770 over2 implementation. They all have their own or none at all. And um that's for safety. They don't want random contracts or and the user really doesn't want random contracts uh acting on their

behalf all of the time and having unlimited authority. Um, and as I was saying before, the user doesn't need to upgrade, but they can upgrade. And when they upgrade, they can only upgrade to the current implementation, not to prior implementations in case of bugs or issues where where an upgrade is required. So what is that solving? It's uh faster registration with or anything with namechain. We can use any chain and token via solvers and relayers or rhinestone and we can in two interactions register a name with an in browser signer involved and it's permissionless. Anyone can execute

either via intents or via 4337 which is very widely supported across the industry. It's also not completely trustless but it's trust minimized with an in browser sign off. execution itself is still uh trusted to the extent that you could have uh you could be frontr run by your solver or relayer uh for the registration transaction. This is something that we'll be working on over time to try and prevent, but generally the financial incentives don't align for a solver or relayer to um frontr run a a name unless it is uh explicitly going to

be profitable immediately for them to do so. Um so some future improvements atomic crosschain swaps. This is because name change is based and so if you are an L2 and you are also based and we're settling at the same layer or even using the same pre-confer we can guarantee execution of a set of transactions on both chains and guarantee settlement at the same time. Um unrestricted burner support is something that we would like to add but again the unlimited scope for those burners is very problematic. So, we need wallets uh or at least some

wallets to be able to support passing what the consequences are for uh signing uh access for the wallet for the signer itself, the burner signer and potentially making it entirely trustless. Not currently sure how that's possible, but it's something that we're looking towards looking into. Um and so yeah, that's about it. Uh if there are any questions or queries then I think there's time for that now.

Oh, >> so I get like the uh HCA stuff as a mapping for when you're doing the registration. >> We can't hear you. >> Can you hear me? >> Yeah. >> Yeah. Okay. So, I get the HCA thing is a mapping within the context of registration. Are there other like ENS like adjacent features or functionality that you think HCAS relate to? Is it really just kind of like isolated for registration?

>> So registration is the most crucial component up front. Um but it is technic like the HCA stack is is applicable to any transaction and every transaction on on the INSV2 protocol. the uh use case for that is more limited to scope in scope if you are looking to just do like a single transaction because you still have to authorize an in browser signer as um an authority on the HCA. So if you're a random D app and you want to set an avatar record, you can't do that without any wallet interaction. You still need

that one wallet interaction. So for apps that are deeply embedded in the ENS ecosystem, it definitely makes sense to be implementing HCAS. Like if you're uh creating subname systems or creating intricate resolver systems that it makes perfect sense, but for everyday like non-ENS specific D apps, it's not really very useful. >> Okay. Okay. So, it wouldn't be crazy if I was like, "Yeah, I could like attach session keys to like a record update that's associated to my HCA or something."

>> Um, I'm not really sure what you mean. >> Like, I update my record and then it signs so that I have like a session key and suddenly I have this window to do stuff. Does that make sense? >> Nope. >> No. >> Okay. I'll ask you off stage. >> Okay. >> Um, yeah. Hello. Can you hear me? >> Yeah. >> Um, yeah. I think it was taped with the demo. You mentioned um that you spin up an HCA in the browser. I was >> um So, we spin up the in browser burner

signer which is authorized on the HCA. >> I cannot hear you now. Okay. >> Uh, can you hear me now? Yeah. Okay. Um, we spin up a in browser burn assigner that's going to be authorized on the HCA via a signature from the users wallet. >> So, we're not spinning up an HCA in the browser. We're just spinning up a burner signer. >> Okay. Um, I don't know if now's the time or potentially after, but could you elaborate on like what that actually means in practice and how it's done? So it's just like a ECDSA signer um in browser like in a secure storage location.

>> Okay. So you're literally just generating a private key and signing on the >> literally just a private key. >> Okay, perfect. And then um I think it's actually to Conrad in the demo. It's obviously a demo, but I'm curious how to in the context of the current uh environment, how that bridging was so quick. >> Um yeah. >> Uh wait, can you hear me? >> Yes. >> Uh uh the the question was how does the bridging work? >> Yeah. How does the bridging work and how is it so quick? cuz my understanding is in practice at the moment at least that um the kind of main constraint and the issue with user experience is people having to wait for a long time.

>> Yeah. So that's traditional bridging. Um there's kind of a new I guess paradigm for bridging called intent bridges which is kind of like well I guess it is the intents that Tate was talking about earlier. So the idea is instead of kind of having these canonical bridges where you either like lock up an asset on the source chain or or burn it there and then it gets minted and then I guess it gets passed through through some messaging bridge and then minted on the other side. You instead have these sophisticated actors called relayers or solvers and you essentially um it's kind of more complicated than that but you essentially send funds to them on the origin chain and then they give you funds on the destination chain instantly. So they already have uh capital like inventory on the destination chain and they would then

give it to you there. Does that >> So that exists now and it really is that quick. >> Sorry. >> So that exists now. That exists now. >> Yeah. >> Yeah. Yeah. >> Okay. Perfect. Thank you. Well, thank you for this illuminating talk, Tage. Um, I wanted to ask you about the the HCA factory that includes the mappings. Is that right?

>> Could you tell us a little bit how about how those mappings will work, how that data is maintained and then updated as well? >> Um, so it's just a one-time operation. So there will only ever be one HCA for any given account. So on the first instance of needing to use an HCA, it'll be deployed and that mapping is just trustlessly set in the factory contract itself. It just knows what the factory uh what the contract address for the HCA will be for that user and then it sets the reverse um resolution. So it sets the HCA address um in the mapping to be equal to the user's account address and

that is stable throughout the entire lifetime of the the user's account or like as long as the chain exists that mapping will be the same >> and and unique and no no possibility of some kind of collision or duplication. the I mean the the potential of collision is is about as likely as the potential of a collision for generating any account. So yeah. >> Okay, great. Thank you. >> No problem. Any other questions? Nope. Great. Thanks, guys.