Santiago Palladino 🛸 Deep Dive into Private State and Execution of Smart Contract
ETHGlobal·Wed, Oct 9, 2024, 12:00 AM
'censorship.wtf' Talks and workshops took place in both ETHGlobal Istanbul, DCxPrague During Devconnect 2023. A full day was spent discussing censorship resistance in the context of Ethereum L1, rollups, applications, infrastructure, hardware, and more. As Ethereum becomes more consequential and its growing ecosystem complexifies, opportunites & pressures to censor increase. While these risks do get discussed, conversations on censorship resistance often center on a specific part of the stack — censorship.wtf was an attempt at approaching the topic head on. ----------------- Follow us: https://x.com/ETHGlobal?s=20 Check us out: https://ethglobal.com/ Email us at: hello@ethglobal.com
Transcript
[Music] I'm Santiago I'm an engineer at AE clubs and well today's talk will be split into three we'll start with a very high level discussion then we'll go very very low level into technical details and then something in between so hopefully there will be content for everyone and also no one that will enjoy the whole talk let's start on privacy sensorship resistance and the link between the two also known as how I convince Tim and Tina to let me get to get me on stage today so uh first of all why privacy um we have said a million times that privacy is a human right and it's not just that it's that the whole world around us is private like our users expect privacy from every application they use where it's Finance it's banking it's voting gaming it's not that if if I don't need privacy if I got nothing to hide it's that everything is and should be private by default uh but the actual question is not why privacy but why privacy at this event right and the catch is that privacy is one of the means one of many uh to guarantee censorship resistance if I cannot discriminate something I cannot censor it uh in particular I really liked a quote by by Jordy during a panel a couple days ago uh when discussing the Privacy aspect of zero knowledge proofs that uh ckps are not a means of hiding but of revealing exactly what is meant to be revealed and nothing else and like that that goes back to a typical example right if I'm opening a back account I shouldn't be revealing my age my race my gender where I live Etc should be just revealing the exact information needed and like I really like um the analogy because with smart contracts we are used at having having code that is low when it comes to execution and with zero knowledge proofs and and privacy we are defining the rules of what exactly gets revealed for each application and we can all agree on that and we cannot have a third party pop up and suddenly start censoring based on information that they shouldn't have had access to in the first place and the thing that the thing is that we have already been using privacy in the context of ethereum uh ready for some time or at least have been discussing about it uh I see that in the second person in a row to have a reference to John in slides uh but for instance encrypted mles is a way to of using privacy to prevent not just toxic M extraction but also to prevent censorship a sequencer that cannot see inside the transaction cannot censor it so hopefully I've convinced you that privacy makes sense in the in the context of sensorship so I can now go into what I wanted to discuss in the first Blick which is how we implement this so uh what is privacy for us in in the context of of the Aztec Network um just the only shield and for setting context ASC network is a private first L2 that works on ethereum that's fully programmable that's all you need to know so we're seeing it as uh private user identity private function execution operating on private state so for any third party Observer of a transaction that happens on the network it should be that someone has done something on some State on some function some contract basically nothing gets revealed want to make sure that there is zero information leaked whenever a transaction is sent while retaining full programmability so how do we do that we do that by moving execution from the sequencer from the notes to the client so whenever a user sends a transaction in the network what we do is we execute that transaction locally and generate a z knowledge proof of validity for that transaction so what that means is that every transaction that's sitting on the pool on the mol is a is a z knowledge proof that proves the validity of that execution with a set of State changes that are completely opaque to the third party Observer and that's it there's no information leaked whatsoever how do we do that basically for every function in every contract on the network which generate a unique circuit so when you're writing a contract in this context each of these functions will be compiled to a unique circuit and we choose to do it that way and not by virtue of a VM because these functions need to be proven client side we want each of these proof to be generated in a browser with one g gigabyte of ram in a mobile device we cannot ask for half a terabyte of ram in order to generate a proof for a for a user not unless not given that we we want the user to keep privacy by running every by running everything locally so how does it look like basically each function each call within the stack generates a z knowledge proof of correct execution and that gets aggregated recursively with another circuit which we we call the kernel circuit taking a terminology from 60 and that circuit takes care of basically gluing together the entire col stack hiding any sort of information the Cur circuit also is going to hide exact which function and which contract executed and produce a single zero knowledge proof for the entire transaction so this means that each of these is each of these individual proofs is small enough to be run in consumer grade Hardware sorry in a mobile phone and then gets aggregated and broadcasted to the network but if we are running um private execution client side on each user we need a representation of state that's amenable to this kind of execution right like in the AVM we have account Bas state that works wonderfully because we cannot we can have multiple transactions all operating simultaneously on the same state here if different users are working together uh it's a bit more difficult to map that to account based uh storage not just that we will also end up leaking information if we have subsequent updates to the same storage slot so for private execution we use a different repres ation of States we take a page out of cach out of Bitcoin and use a utxo like model in which we have custom notes representing State and I want to highlight here custom like every smart contract every every Dev can Define the shape of the nodes for representing their own State like for a payments application or for for a token let's say uh a value note that just carries the the value the amount of funds in that particular note is enough which is the the shape that we're already used to but let's say that we're building something like a card game like a magic The Gather Magic the Gathering inspir one in which we can represent for instance each card with a specific note that has the attributes of that particular card again the nodes are the representation of state and are not bound to financial applications they are completely custom and used to represent arbitary State now these notes uh are stored locally by each user user so each user has their own representation their own private state which is kept locally within their wallet but we need to map those notes that private state to the global blockchain state right this means that and whenever uh I want to send information to another user I create a note for that I encrypt it with a recipient public key and broadcast it through a network so to to make sure and to probably send it to them but they also need to create a commitment to that note in what we call a global data commitment Tree in other words if I if the only proof I have for using a notice that I have it locally users could be able to create notes create State out of the ner so whenever a note is created we have a commitment a hiding commitment to it in what we call a private data tree so whenever a user need to generate a proof that uses this particular piece of State they need to prove membership of that note in the in this Markle tree consuming a note basically deleting a note render it outdated is done by nullifying the note note is nullified by emitting what we call a nullifier which is a hash of the note mixed with a secret uh generated by the user in a deterministic way such that the nullifier cannot be linked to the note commitment in other words when we create a note we add it to a an append only tree when we want to consume a note we just register it was used without without any observable link back to the note this allows us to update notes to change State without having any link between the transactions how does this look in code we are using Noir which is a rust like DSL for writing circuits augmented with a framework for writing contracts and having easy interaction with private State here in particular we have an implementation of a of a very simple counter contract that keeps a counter for different users and allows incrementing them and what's interesting is how this is Implement how this is implemented with nodes under the hood so what ends up happening is that we have one note representing state in this case one note for each counter of each user and we want when we want to update it we consume the note with the old value Again by emitting a nullifier and create the new one so basically updating state is deleting the note that represents the Old State and creating a new new one and by virtue of nullifiers there is no link between the two operations so we're effectively updating the same slot without revealing any linkage between the two it's also worth mentioning that whenever a user needs to read a value of a note needs to create a proof by using a value of a note we need to destroy the note and recreate it with the same value why because if execution happens in the user device it needs to happen on an old version of States like the user doesn't know where the when their transaction will land in a block they they don't know what's the exact state that their that their transaction is going to operate in that means that the only way to ensure that they have a fresh version of state is by consuming it and generating it again if they happen to be using an old version of State they would be emitting a nullifier Associated to that piece of state it would already be in the tree and it will be registered as a double spend which is the only other condition we have for validity for transactions transaction actions are Z knowledge proof and are valid as long as that proof is valid and there are no duplicate nullifiers so bottom line here is we have um we have a state representation that allows us for each user to run functions privately generate the proof of them and broadcast those changes in an Opa way however it's worth mentioning that if whenever if every time we need to read the value we need to invalidate it and recreate it which implicitly invalidates all other transactions in the pool that we're referring to it this doesn't align well with um with comp with composition right like it's known that c snarks are maybe not the best tool not the best tool when it comes to concurrent updates to the same share private state so for instance uh this model is great for implementing a private order based decks but not so good when we want to do an amm where we have a single shared constantly updated piece of data such as the the liquidity the the amount of each token in the pool that gets constantly updated so to address that the network actually runs a hybrid model private and public what does this mean this means that every transaction along with a set of aex the changes Al can also emit a set of execution requests and here we are in the land that we're that we're familiar with basically the transaction asks the sequencer to run a series of public executions on their behalf and here public functions map to an account byas State similar to the to the one from the evm and can congruently operate on the same state over having this um this duplicity of both private and public state in the same chain makes it easy to run operations such as Gathering and unlocking funds based on some sort of private condition then swapping them in public State and then sh shielding them back into private State the idea is that every private transaction can inue a set of requests to be executed in public but how the developer uh manages this difference allows for this duplicity of okay what needs to be run in private what needs to be run in public what's the problem here even though we have made composability easier now we're introducing a censorship Vector we're starting to reveal actions that transactions do and with that let's go into the third and last part of the talk which is about the decentralization given that we're building a network private first in which censorship is of the utmost importance we want to make sure that transactions cannot be sensor cannot be stopped and for that we are designing sequencing and proving protocols that are both fully decentralized that are going to be decentralized from day one the network is not going to launch without fully decentralizing sequencers and provs Progressive decentralization is not an option here and we're also working on governance mechanisms that are compatible with them that can provide Security provide upgrade paths but guaranteeing the censorship resistance of their users and we are doing this decentral this decentralization in a decentralized way we are putting out and we have been putting out rfps throughout the year asking the the community cont to contribute with proposals for each of these areas and we'll continue doing this and we really really encourage you to jump into the forum Link in a couple slides and help us help us here uh we are converging to a sequencer selection algorithm called fernet apparently Argentinian guy named it which basically depends on random elections of stake stake sequencers on the on the network uh based on a verifiable random function the idea behind this is having promoting the central ization among the the set of sequencers and we're currently evaluating different options for proving that pay well with the sequencer proposal both cooperative and competitive networks in competitive networks we want we know that we can foster Innovation competition between the different providers in researching better techniques for faster and cheaper proving and in competitive in Cooperative networks we know that we can foster a higher diversity which should lead to lower censorship in particular in Aztec we are we have designed the rollup topology that if we want to allows us to parallelize the proving across many many different machines that can run in consumer gr Hardware like each of these each of these small nodes within the massive proof tree should take no more than around 32 gigabyt of ram give or take so again we can completely priorize and decentralize the proving activities so so to sum up we have a lot of problems to figure out a lot of challenges ahead and I encourage you to please join the Forum join the discussion help us build strong robust healthy private and sensorship resistance protocols uh not just for the network that we're building but also to generate open source knowledge that can ideally help all other networks in in the ethereum ecosystem thanks
Automatic transcript — names and jargon may be misspelled.