 Okay, yeah, I'm Mike and I'm gonna talk to you about public private composability and what that really means is I'm gonna talk about Aztec's private smart contract architecture. So we've specced it all out and we're gonna be spending the next year maybe more building a general private smart contract platform for Ethereum. So what were our aims when designing this private smart contract platform? Well firstly private states and what private states are are values known to only one person. So a private state has an owner and no one else in the world knows the value of that state. Okay, and then private function execution and this is really cool. This is the ability to execute a function without revealing to anyone in the world which function you've just executed. So similar to like the Zexi protocol. And we want people to have a similar experience to Ethereum. So we want people to be able to deploy contracts permissionlessly. So just any time you want to deploy a contract of the system you can just deploy it. And again similarly to a Ethereum experience we want composability. So we want someone to be able to call a function and that function might make a call to another function of another contract. And that function might make another call to another function of a different contract and so on. So that's really important. And we want a different kind of composability as well. We want composability between private and public functions which I'll talk about more as we get into it. And altogether we just want intuitive transaction semantics. So we don't want a developer to have to think about the underlying cryptography or any of that. We just want them to have as close to a smart contract experience that they have with Ethereum. Okay, so I'll take a step back. What fundamentally is a smart contract? Well at its core it's just a collection of state variables and a collection of functions which may edit those state variables. And here we can see a noddy example of an ERC-20 contract. Balances is a state variable and there's a function called transfer which has rules which allow people to edit the balances state. And there are two to the 160 such balances states in this example. But what would an Aztec smart contract look like? Well people will still be able to write functions and states in for layer one, so for Ethereum. They'll also, similarly to all the other rollups in existence, the ZK rollups and the optimistic rollups, they'll be able to deploy functions and have persistent state on a layer two just to save on costs. But the key differentiator with Aztec contracts is there will also be private functions and private states. And crucially you can see here these will be on a user's device rather than executed by Ethereum nodes or a rollup sequencer. Okay, so what do I mean by private state? Let's look into it a bit more, get everyone up to speed on some background. So a public state is just a value in a Merkle tree. It's the same in Ethereum and it'll be the same on our layer two. What's a private state? Well it's just a commitment to a value in a tree and it has an owner. So here we can see an example of a commitment. It's got an owner public key. It's got some value that you want to hide and store persistently in our layer two storage and it's got assault, which is something random to give the commitment hiding properties and maybe some other stuff depending on the application that someone deploys. Public states will follow an account model just like states in Ethereum smart contracts. And with the account model, a state lives at one position in a Merkle tree, one leaf, and will occupy that leaf forever. So if someone ever wants to edit that state, the person executing the contract will have to go to that exact leaf position, modify the value. But that's no good with private states because if you have to tell the whole world I'm editing this particular leaf of this tree, please update your node accordingly. You've revealed which state is being edited, so that doesn't work. Which is why we adopt a UTXO model. And in a UTXO model, once you add one of these commitments, one of these hashes of a private value to the tree, it never changes. If you ever want to edit that state, similar to the Zcash model, you have to nullify that state, which allows you to change it or prevent it from being used again without revealing. And you have to add a new commitment to the right-hand side of the tree. So you're always appending new values. So if someone comes along and they want to edit your state, they will create a new commitment representing maybe the add-end that they want to add to the state or something like that. And just to continue with the background and carry on with this Zcash-like protocol description or indeed our current Aztec Connect protocol description, let's say someone inputs a commitment into their circuit and they want to modify the value contained within that commitment. They pass it into the circuit. The first thing they would do is prove that this commitment does indeed exist somewhere in the Merkle tree of notes. And in Aztec Connect, the Merkle tree is 2 to the 32. With this private smart contract platform, it might be quite a lot bigger because apps will probably create a lot more commitments. Okay, the next thing you do is you open the commitment and you would hash the values to prove that you indeed know the pre-image of the commitment. And Alice in this example is the owner of this state. And so for her to prove that she is indeed allowed to modify the state, she has to prove knowledge of a secret key. And she can do that by just hashing it, or following however the secret key is derived. And then she produces a nullifier. And the previous talk was quite helpful because it explained nullifiers so I don't have to. And then they prove it doesn't yet exist in a nullifier tree. And the nullifier tree at the moment is a sparse Merkle tree. It allows you to prove non-membership. But we're actually going to update this to a linked list tree, which allows you to prove much more efficiently that something doesn't exist in the tree. And suppose Alice wants to perform some simple operation on a state. The circuit, she'll add 5 to it. And you can see we've incremented the value that Alice is hiding. We've changed the salt to re-randomize the commitment, and she adds it into the tree. So this is quite a general way of just modifying state within a public protocol. And crucially, this step has to happen on a user's device, or at least in the most basic systems, this has to happen on the user's device. You can do some delegating schemes, but we won't talk about that here. And so this gives our roll-up something different from other roll-ups. There is a layer where if someone wants to modify a private state, they have to do it on their own device before then passing it to some sequencer who will deal with all the public state changes. And indeed, because it has to happen on a user's device, possibly in the browser, we need extremely efficient proving systems, which we've been working on and we're continuing to improve. So on an L2, functions are slightly different from a Solidity function. They're actually ZK snark circuits, so similar to other ZK roll-ups that you might have read about, except our roll-up will need to be actual ZK, so provide hiding properties. So if someone begins with a circuit, suppose they write a circuit in some circuit language like Noir. They write the rules of their function, you know, it might include state changes, computations, stuff like that. And using something like Noir, they can take that circuit and compute a proving key and a verification key, and a user will come along and they want to execute this function, or rather prove that they have executed the function correctly. And that function will take some secret inputs and some public inputs. And they'll pass it into Noir, a big black box, and it will generate a proof. Out will come the proof. And you can send the proof and the public inputs to some verifier who already has the verification key, and they can verify that you did indeed execute the function correctly for the given set of public inputs. One thing I want to point out in this slide and that we'll need going forward is that the verification key can be used as a unique identifier for the circuit, because it was derived from the circuit. And the hash of the verification key is like a unique single number that can completely represent the circuit. And yeah, this can all be handled by Noir. So if a verification key can represent a circuit, and if a smart contract is a collection of functions, then we can create, well, we can represent our set of functions as just a set of verification keys. And if we want to prove one of our objectives that we have executed a function without revealing which function we have actually executed, we can just merkelize all our verification keys into a big tree. And we can add our contract or our set of functions to a giant contract tree, which contains all functions that have ever been deployed to this layer two smart contract platform. And in doing so, if this computation, a merkel membership check is done within a circuit, you can hide which function someone has executed. So Zexi already came up with a system, which was really good a few years ago. It's a good paper if you haven't read it, for hiding which function has been executed. And this hash here represents a commitment that someone might add to a tree that we talked about earlier. And within the commitment, they had a nice idea that you would put in a birth predicate, i.e. details of the function which created this commitment, and a death predicate, a function which the only function which may nullify this commitment. But if people are familiar with solidity smart contract development, it's not quite good enough to just have one function or modify a state. You might want multiple functions to be able to modify a state. Which is why in the previous slide, we've kind of collected all possible functions of the smart contract and add them to a contract tree. And so instead, what we do in our smart contract spec is we include a contract address. And that represents just the set of all functions which may edit this particular state. And again, this is how Zexi proposed to hide the function being called so that no one knows really what's happening in the system. You know, all observers see is that some function got executed according to some set of rules for some smart contract. You take the private circuit and generate a proof. And if we stop there, the world would see which function got executed. So we pass the proof into this kernel circuit. And the kernel circuit verifies the earlier proof and kind of masks from the world which function got executed, which is really cool. And we take this and we take it a step further, which I'll talk about in a second. I'll talk about it here. One of the things we said, one of our aims is the ability for functions to make calls to other functions and so on and so on and so on and so on. So how are we going to do that? Well, first, why would we want to do that? Here's a really simple reason. If you consider a decentralized exchange, just on layer one at the moment, if Alice wants to swap tokens A and B, she must first call the exchange contract. And then the exchange contract has to call the ERC-20 contract for token A. And then the exchange contract has to call the ERC-20 contract for token B. So the most basic kind of applications on Ethereum require nested function calls. And we want to mimic that with our private programming, smart contract language. What does a function call look like? Well, in Ethereum, it's a contract address, some identifier for where people can locate the function and a set of arguments. And so similarly for Aztec, it will be the contract address. The VK index, as we saw in the previous slide, the verification keys all get added to some contract tree. And a hash of the public inputs to the circuit which represents a function. So let's work through an example. And you don't need to read the code for this or you need to really look at as the colors. So we've got to imagine someone called the red function over there, function one. And the red function is making call to an orange function in a different contract. And in turn, that orange function is calling a blue function in a different contract. It's returning some values. And then it's calling a green function. And this green function is a public function. So what I'm going to try and demonstrate is how functions can call functions of other smart contracts and can also, you can have functions from private world to the public world. Well, what we first have to do is each of those individual functions is an individual circuit. And so you would have to generate six distinct proofs, one for each function that you want to prove you have executed correctly. But then the question is how do we prove that they relate to each other in a way that the code wants them to relate? So how do we prove that they were executed in order and the parameters that were sent to functions and the return values all intertwine correctly? Well, we use call stacks. So say we want to execute function one first. Well, the public inputs to every single function on our smart contract platform will have to adhere to a very rigid static ABI. And one of the fields in that ABI will be call stacks. So because function one makes a call to the orange and yellow functions, this circuit will expose through its private inputs the call arguments and the function signatures of the orange and the yellow functions. And similarly, the orange function is making a call to the green function. So, oh, and the blue function. So it will also expose calls to the blue function and the green function in its public inputs. And notice the green function is labeled as public. And so because public functions get executed by the sequencer and private functions get executed by the user, they have to be separated in this way. And on we go. The green function is making a call to the purple function. So we add that to the call stack. And here's the really meaty cool bit. And that's kind of extending the the zexy example we saw before, where if you pass a function into a kernel circuit, it hides which function has been executed. We add some extra logic to our kernel circuit to allow these call stacks to be interpreted and to check that the parameters being passed between all these functions make sense and are according to the rules of the smart contract that somebody wrote or smart contracts for all that some people wrote. So we begin with function one. We pass it into the private kernel circuit and the private kernel circuit will read the public inputs of function one and push on to its own call stack the two items that function one makes a call to. And then we will carry on with our recursion. The private kernel circuit will spit out a proof and we will pop the next call from the call stack and we'll pass it in to another iteration of the private kernel circuit. So each of these arrows is a proof and within the private kernel circuit two proofs are being verified each time. And so we can see the call stack has shrunk a bit and then we pop call number two the orange call off it and pass that into the private kernel circuit. And we do recurse until the call stacks are empty and then we know we're done except the orange function is making calls to another two. So we'll just keep going until okay finally the private call stack is empty and therein ends the work that needs to happen on a user's device. So because the user only executes private functions, public functions are executed by the roller provider. This proof here will be sent to the roller provider. What will the roller provider see? Well they'll just see that somebody executed some function of some smart contract and changed some kind of states but the roller provider will have no idea which which is really really cool. What they will see if the private function is making a call to a public function they will be able to see the public functions which need to be called. There's no way around that. So seeing the call stack as it is the roller provider will take this function and execute it and pass it into a public kernel circuit which has instead of hiding logic it just executes states out in the open similar to I guess other ZK roll-ups. And this function is making a call and we're almost done. We pass that into the kernel circuit and hooray the call stacks are empty. We finished executing our function trace or our stack trace and this can then be sent to the roll-up circuit. This entire thing represents a single user transaction on our smart contract platform and it can get rolled up with all the other transactions. You don't need to read this. All this is saying is that the in order for the kernel circuit yeah in order for the kernel circuit to be able to operate on any kind of function we need one giant static interface which accommodates as many possible function permutations as possible. And that's what these interfaces are. There's one for private circuits and you can see there's a lot of arrays to allow for various sizes and various permutations of stuff that an app might wish to do or a function of an app might wish to do and we got one for public circuits. Similarly the private inputs and public inputs to the kernel circuit there's loads of them and there's a lot happening. There is so much computation happening in these kernel circuits that we've been working on a better proof system, more efficient proof system for ZK Snarks and it's actually similar to Hyperplunk which espresso systems have been working on. It's really cool idea and I guess there'll be more on that at some point in the future. So we have this transaction and I mentioned when we get to this stage it gets sent to the roll-up. What does the roll-up topology look like? Well first I want to point out that that example transaction was doing some private computation for the user and some public computation but it doesn't need to be that way it can just be this transaction is just public computation similar to other ZK roll-ups or it can be completely private computation you can think Zcash transactions are completely private so you could deploy an app which does Zcash like transactions on this smart contract platform and I won't go into it today but there's also the ability to deploy contracts and you can even have similar to Ethereum functions deploying contracts for you from a smart contract. Okay so we've got these transactions and they get sent to the sequencer or roll-up provider and this sequencer is going to compress compress compress compress until level left with one proof and the way you do that is by verifying proofs within circuits. So this base roll-up circuit verifies two proofs and this one verifies two proofs and then we go to the next level and we verify two more proofs and then we end up with one proof and because the proof system we use here ends up being quite expensive to verify on Ethereum we'll squish it down to a cheaper proof like Plonk or Gros 16 and then send it to the smart contract. Right and then within the smart contract this proof will be verified and the state trees of all the various trees we're managing will be will be updated or other the roots of the trees will be updated. Okay and I think this is the final slide so what I want to point out here is that there's always this arrow of time with these transactions so you begin with a private function executions or proving you've executed private functions always on the user's device and once you've done that step then you can go send your transaction or your call stacks to the roll-up provider who will execute their stuff and will ignore the contract deployment step and then it gets sent to the roll-up contract and from there similar to Aztec Connect if you've looked into it you can then make calls to any smart contract in Ethereum and interact with any DeFi contract that already exists but suppose your private function wants to make a call to a public function or to a layer one function and receive return values well it can't receive return values immediately because of this arrow of time and the order things need to happen excuse me so you'll have to wait until the next roll-up and so what we have and I don't have time to go into it here is if a private function is making a call to another layer of this stack it will have to record callback functions similar to if you're working with JavaScript and those record of those callback functions will be added to a tree and then in the next roll-up the user will have to prove that they are executing the correct success or failure callback function in order to carry on with the execution of their function so there's a lot of complexity there we've written a lot of documentation which I think we're going to publish which kind of explains all of this complexity but yeah that's everything I wanted to talk about today oh and I guess I do have time to just briefly say what the kernel circuit does it does tons and my throat's hurting so much that I'm not going to through go through this but feel free to take a picture and ask me questions afterwards yeah thanks very much we still have time for one question maybe someone wants to do a question we have our volunteers with the mics there you're here to the left and maybe one there dependent on time and one thing that you didn't touch it on the presentation was about the participants you mentioned in the beginning that you might have a visit with participants and so example go quorum with the Zeta and best with the Zeta which I'm sure you are aware they are platforms that allow you to have public and private state contracts they have different ways to tackle it so best of those like groups you define your group and that group will share a private state and go quorum which is a fork of get with modification for private state allow you to like select for each transaction which participants will see those changes and that means that you can have the versions on the state so like you might have a transaction that you change one smart contract and you change and you apply that state change for two participants but then in the next transaction you change the same value and only one participant will see it not the other how do you solve that in your platform I didn't fully follow the long question maybe we can chat afterwards sorry about that you can chat outside that's the great place to do networking and to get to know more and we have one more question there please sound to that mic hello just one quick question is is these private call for contracts already available in nestec or it's going to be in the next release so we'll be releasing the specs but we haven't built this we're kind of we've begun building it and but it's we're probably maybe a year away from testnet so yeah it's a it's a big beast big round of applause once again for Mike Connor thank you