 Hello, hello everybody So looking forward to the next talk Who is who is here for for zkps? Who thinks who thinks? Zkps are the greatest things that blockchains Ever enabled into space in terms of getting it funded That's just my personal opinion though But I think zkps are actually the the nice thing that nobody expected coming from cryptocurrencies, but they still happened So next up we have Henry de Valence the founder of Penumbra, and he's going to to be talking about their experience of building a Privacy just disappeared in front of my eyes because the talk is starting now, but Henry is building a privacy preserving decks Using zkps. So please put your hands together for Henry. All right Yeah, well great to see everyone So I'm going to be giving a talk about how to build a private decks. However, just as a kind of a pre-warning if you're really interested in all of the sort of details of zk proofs that actually won't be covered in the talk and the reason is that I think part of the problem with deploying zkps for Privacy rather than just for scalability is that there's some interesting and fundamental challenges in The state model. So that's actually sort of the whole summary of the talk. So to get started For context, so I'm working on a project called Penumbra What that is is a private proof of stake L1 Inside of that L1 we have an interchange shielded pool so you can take any IBC compatible asset Move it into this chain and that's the the privacy boundary. So as it moves in it's recorded in this shielded pool And the cool feature that we have is this private decks that's integrated with that shielded pool on top of that Privacy preserving base layer however I'm not sort of here to just you know Chill the project. I'm here to talk about the kind of technical aspects and specifically what are the challenges to actually building this system So the first challenge is oh, sorry So just as a bit of motivation right like why do we actually care about having a Private decks in the first place The thought is that every market is also a market in information when we talk about price discovery for instance You can think of that as being a kind of decentralized Computational process that as a side effect produces some information about prices But that means that information leaks are value leaks When people talk about MEV and have these you know dashboards of here's how much value is extracted from people who are trying to do trading Really, that's just the sort of first order symptom of this problem. It's not even if you fixed MEV in some way You still have the problem that You're you're leaking information about what trades you're doing What trades your account has done your entire history of your whole trading strategy? All of that information is valuable too. It's just harder to make a dashboard of it so the the thought here is that privacy is a really interesting thing for Trading because trading is a context where having privacy allows you to unlock greater capital efficiency and As somebody who's really interested in privacy, you know for its own sake as a value as a human right etc This is a really interesting and exciting Opportunity because it means that there's the potential to build a private product that can actually Outcompete the non private ones because it's private So we we get out of this mode of like oh well We'll you know have people accept all these trade-offs to use the private thing No, we're gonna build something that's better because it's private. So right I said I was gonna talk about the challenges and The first challenge which is the most fundamental is actually the state model So if we consider a transparent chain like Ethereum the the paradigm of that state is global mutable state There's like one big Ethereum state and every transaction is applied sequentially and it can do whatever mutation to that state And as it's doing that mutation effectively, it's taking like a global lock over the whole state Doing some changes then you do the next transaction and so on but in order to have a Shielded chain where the user state is not public information We have to change the state model to a model of immutable Composable state is actually kind of like you know historically speaking. This is sort of rewinding to a Bitcoin style sort of UTXO model but I think UTXO is a little bit of a loaded like baggage-laden terms So I prefer just having this idea of a state fragment and Instead of having one big global state We're gonna have a tree of state fragments which are immutable and each transaction is gonna Consume some state fragments produce some new ones and put those, you know append those into this tree The reason that we want to do this is that that way we can make the state transitions private and the move to do That is you replace all of those state fragments with Cryptographic commitments to states and then in your transaction rather than explicitly declaring the plain text values of those state fragments You can just have a zk proof that the state transition was valid and here are the commitments to the new states that I've produced Okay, so this is all cool and that's why everybody's like using like Private blockchains all the time. No, why is that because that diagram isn't quite right In fact what you're submitting to the chain is this zk proof pi That represents the state transition But what we've actually done is we've moved all of the execution off chain along with moving all the user data off chain, right? But now we don't really have any way to access any shared state because when somebody's submitting their Transaction effectively every transaction is its own little micro roll-up And what I would claim is that the key problem here is is one of early versus late binding so what we have in this sort of zk model is Early binding every transaction has to have this fully sealed Complete state transition, but that's not actually what we generally want right if you make a trade on uniswap You're not going to sign over here's the exact state of the uni reserves of this contract Here's the exact outputs that I'll get because The only way that you could do that is by sort of having the entire world stop while you you know submit your transaction Right what we want is the ability to have a partially filled transaction Where we can have some placeholder values where when the transaction is executed The the shared state is going to go in that spot and then it'll determine some outputs so In order to make this work with the sort of zk model where we're keeping all of the user data off-chain We need to have some better concurrency model for shared state right fundamentally The problem is that if you're doing this off-chain execution you need to have some kind of like exclusive control over the the data that you're executing on and You can start with the kind of oh well will take a big global lock and you can make the locks you know smaller but The the more interesting idea I think is what if we try to model concurrency with message passing Rather than locking if you look outside of blockchains that just kind of like normal, you know high performance high concurrency software systems You can do better by having finer locking but a cleaner and more scalable approach is to have different parts of the system Executing independently with their own state and passing messages back and forth to each other So what would that look like in the context of trying to build a privacy preserving chain? Well, we could try to think of this kind of actor model for chains where a transaction rather than Synchronously doing a contract call where it locks some state does some Execution and then finishes and releases the lock we could say that a transaction is going to pass a message to a contract Now we're gonna have each contract execute once per block But as it executes it's gonna receive the set of all of the messages that any transaction passed to it And it can process those all in a batch and depending on you know the specifics of that contract logic in some cases You know you could combine all of those messages into one right like you could do a batch swap Which I'll I'll get to later on in the talk But also you could imagine say like an auction protocol that orders these messages by the bid amount And the key thing is that you're not doing any execution at a higher time resolution than is actually provided by the underlying consensus right when people talk about transaction ordering a lot of the Problems arise from this mismatch between the economic mechanism in the contract Which is trying to execute at this sort of faster than consensus speed and the actual you know Consensus ordering guarantees that are provided by the blockchain which happen block by block right like if you're agreeing on Transactions in in batches like maybe you should also be executing in them in batches and on the other hand our per user state we can still have this sort of off-chain Execution, but now the execution is going to be asynchronous right when I consume my state And I pass a message to a contract. I can't compute my outputs yet because I haven't got a message back So I need to somehow record this sort of intermediate future That represents the eventual results of the computation that I'm going to be doing But I can do all of the All of the computation that is only touching a particular user state can happen off-chain Privately in zk. So the really interesting thing about this model is that it actually Simultaneously unlocks both scalability and privacy because all of the data that doesn't need to be having any shared execution Is happening that execution is is happening on each individual users? client and The on-chain data is limited to the minimum Shared computation and it's executing in a batch so you can potentially have a much more efficient implementation So to see kind of how this works in a in a diagram Which I think it might be a little bit more clear. We're going to start off with our first You know somebody's preparing a transaction. They're going to perform a state transition and produce a zk proof of it with their private inputs and That transaction is going to send a message out to this contract What it's going to record as the output of that initial transaction is actually a privately minted state NFT Which commits to the future that this computation is supposed to be Representing so now this user has this in this diagram This is the the diamond is this NFT that records the kind of intermediate state of their per user computation After they send that all out to the chain. It's included in a block the chain is going to send a message back by publishing data to the chain or the contract is going to send a message back by publishing the data to the chain and We take that message from the contract combine it with our intermediate execution state we're going to burn that state and Inside of this zk proof we can now Prove that we've you know modeled the correct future with the correct You know same input values that we had committed to in the first transaction and now we can privately mint some outputs So this is this sort of big picture diagram of how this sort of async zk execution can work In principle And we'll get to a concrete example of how that works out for the case of doing batch swaps but before that I just want to get into the second challenge which is Once you have an idea of okay, we have maybe a workable state model, but what is the privacy model, right? and The claim here is that basically every useful blockchain revolves around public shared state That's why you know for instance, Ethereum is valuable because it has everybody's state in it and it's all there So the idea of like oh well We're gonna just like make everything private and like everything will be completely private doesn't actually work because in fact Like the reason that we're we're using the coordination tool is So that we can coordinate nobody wants to use a market where they have no idea what the liquidity is Or what prices they might get or you know, what the volume is and all of the the sort of big breakout successes of Useful contracts have the contracts Public shared state acting as this kind of universal counterparty So you don't need to go and find some some person to interact with you can just interact with the chain So we need to have public shared state, but you know, maybe we want it to be private So what what does that mean exactly right this question? The question is like how do you allow? private interaction with public shared state we want to have some kind of notion where the Individual users transactions have privacy, but all of the aggregate state of the chain Like you know all of the aggregate market data is public, but the individual users trades are not so here's two basic strategies of how you could have Private interaction with public state one is splitting flows and the other is batching flows when I say flow The reason I would use that word is that I think of you know value being in in different sort of pieces of the chain state and as people do things you're gonna have flows of value between different portions of the chain state and we want to have some kind of system where people can Have privacy about what their contribution to that specific flow is but still have a sort of overall Transparent aggregate so looking at these two in turn For splitting flows the idea is that we're gonna start off with some users Value that you know this maybe this is an amount that they want to trade They can split that into randomized sub amounts and then reveal each of those sub amounts in distinct transactions and then reunify them later So this method only works if you have a shielded base layer if you have a transparent base layer Then this like is trivially broken because you just like look at what the account was and then you can see what it did But if everything else is private and you're only revealing like here is a specific amount that I'm sending to this part of the system Like this is a public delegation amount to some validator This is like an amount in in one sort of randomized sub trade this might be okay and It's a it's a fairly practical and simple thing. However, it's it's not really ideal So the other strategy which is more interesting and more cool is this idea of batching flows So if we know that we're already going to be processing The contract state in batches it would be nice to have a way to batch up flows We do this using a construction that we were calling flow encryption, which is effectively additively homomorphic threshold encryption With sort of end-to-end verifiability once you've tacked on, you know six different properties You might as well give it a distinct name But the idea is that each individual user with their You know distinct contribution to this flow can encrypt an integer amount Include that in their transaction and then the validators can sum up those encryption's and decrypt only a batch total so that there's the batch total and The idea is that now you can use that as the input to some public on-chain computation But still have long-term privacy for individual transactions You know as long as the batch sizes is big enough as an example if you're trying to have You know a Delegated proof-of-stake system you could make it so that oh the validator weights will change You know in each epoch and we'll just sum up all of the the delegations or undeligations in each epoch and only reveal the net change So these are sort of the two pieces. Let's see how this kind of works out As a concrete worked example Which is doing sealed input batch swaps on penumbra So looking first at the private state part, right? Remember that we have this model where we explicitly segment away the per user private state from the shared public state We're gonna start off with okay. Here's the the private input for this trade that a user wants to make They're going to Encrypt that input include that in their transaction the rest of the transaction right is is totally shielded because we have this Shielded base layers. There's no public accounts or any other metadata in the the transaction and what they'll mint in that swap transaction is a Swap NFT where the asset ID of that NFT is a snark friendly hash of their input trade amounts the trading pair they're you know the address that they're gonna mint the funds to some prepaid fees And as this transaction that they submitted is included in a block it gets batched together with the others decrypted you Send that into the Dex engine which resolves all of the trade intent and publishes the output data into the chain state and now That user can consume their swap NFT which remember is modeling this sort of future that resolves eventually to their swap outputs and produce a proof that uses these public batch swap data as a as a public input and their Swap NFT is a private input to privately mint their correct pro rata share of the batch swap and so That that means that that individual users output can be minted completely privately and as long as you have sufficient Sufficient volume in the batch You can get long-term privacy for individual users trade amounts now if you're on say like a thinly traded Pair maybe you end up in a batch size of one But in that case you can use this sort of randomized splitting technique that I mentioned earlier to make effectively a kind of like randomized T-wap of your trade so Zooming out of the the private state part to how this works on the public state side We have all of these All of these swap transactions that have been included in the block We have the dex engine group all of those inputs by pair We do this batching and decryption, but now at this point. We we don't just have you know a single Swap we don't just have a single swap transaction on a single pair We have a complete picture of here's all the trading intent for the entire chain in this block and We also know that we only have to run the dex engine once per block Because we're in this batched computation model So that means that we can actually be you know considerably more sophisticated in how we resolve these trades we can load up the entire liquidity graph of all of the assets on the chain sort of put the trade intent into the correct spots on that graph and then compute Some optimal resolution of all of these trades Simultaneously, so you can do some kind of global resolution of the trading intent do optimal arbitrage and This is computationally tractable to do just like in consensus Because you know that you're only doing this once per block So you you end up in the model where rather than sort of having to call each contract You know potentially like thousands of times of block You just know that the chain is going to step in Distrete time from one set of consistent prices to a new set of consistent prices you can handle all of the newly added or removed liquidity Also in a batched way right so you first add all of the newly created liquidity Then you resolve all of the trade intent then you are above all the prices to be consistent with each other Then you close all the you know closed positions, and this also lets you as a side effect have like single block Jit liquidity With the kind of like batch semantics, so there's a lot of really interesting pieces of market design that get unlocked by this model So that's basically the content of the talk if you want to play with this We have some weekly test nets that you can you know play around with here's a bunch of links So far the the big last sort of piece to build is the the actual dex engine, but we have a toy AMM that you can do these shielded swaps against on our test set So that's the talk if anybody has any questions Happy to get into it Just wait for the mic, please. I'll run to you with the mic Thanks for the talk just curious So have you found a tight bound for how much of a loss you have when you provide batching because if it's a Constant-function market maker a loss in what sense? So you're gonna get an average you're smoothing it out in that sense of speaking so you can actually have a spike in a block You're just averaging So have you done any analysis? I did some analysis, so I'm curious if you have done that So I guess the the question though that I have is like a loss relative to what right assuming no private So two worlds same block private versus non-private I'm No, okay, we have more questions. Yeah, they're not sure who was first sorry Just a quick one. Thanks very much for the talk. This is fantastic to hear and to get this content and this My quick question on reverts the whole batch reverts All right, so I admit that on reverts the whole batch reverts If it transaction reverts. Oh section is not valid. Yeah, so It's possible for instance that someone could submit a transaction that Say, you know, they submit a trade for a trading pair that doesn't have any Liquidity on it, right? So one of the outcomes of the batch swap is that the trade can fail and in that case rather than having people privately mint Their pro rata share of the outputs. They privately mint their pro rata share of the inputs. They get their their funds back Yeah, so the whole batch goes goes at once so like technically I guess you could have some kind of griefing attack where someone is like continually locking up capital in trying to like prevent other people from trading by Submitting a giant whale trade, but like they can't actually do that without running the risk that like someone will provide liquidity at a bad price So I think it's probably not a big deal Right. The time is off. Well One more round of applause for Henry, please Thank you, Henry