New Ethereum talks, every Monday. The week's conference uploads by event, in your inbox.

Loading player…

Learn ZK in 90 min: A Collaborative Workshop with Mina Protocol

Ethereum DenverMon, Oct 9, 2023, 12:00 AM

Mina's zkApps are smart contract applications powered by zero knowledge technology, which offer privacy, security and verifiability for users. Join the Mina community in Denver and learn about ZK, use cases, and starting building your first app during this hands-on workshop.

Transcript

All right. Are people ready? Cool. All right. We can start the stream then and I'll get started.

So, this is uh we're going to learn ZK in 90 minutes. This is a collaborative workshop with the Muna protocol. Uh this QR code will appear at the beginning of the presentation throughout it and at the end and it links to a notion page that has a bunch of relevant information you know discords uh links to the GitHub um programs that we'll mention throughout the presentation etc. So the idea being you don't have to worry about taking notes or jotting anything down. We have notes taken for you already and you can just scan the QR code to get them.

Uh, oops, sorry. Uh, again, if you haven't installed the ZK app CLI or cloned the repository, you can do that if you want to follow along. Uh, you don't have to if you just want to sort of watch and learn. Okay, so uh, who am I? I am Jack Servia.

I'm a developer relations engineer at O1 Labs. I'm based in Denver, Colorado. I was born in Denver, Colorado, and I plan to live here forever basically. Uh, and that's my my Twitter. Um, okay.

So, what's O1 Labs? Who's building Mina? What's Mina foundation etc. So uh Ovin Labs is a basically a zero knowledge technology company. We built the proof system for uh the Mina protocol and also the reference node implementation.

Uh Mina Foundation is more akin to the Ethereum Foundation. They do things like uh sort of steward the whole ecosystem. They have very cool programs that we'll talk about later on in the presentation. Um, and uh, you know, if you're looking for a grant or or if you're looking to, you know, do something kind of big picture in the ecosystem, they're probably the people you want to talk to. So, it's not just Owen Labs and Mina Foundation that are building Mina protocol, though.

Uh, there's actually a whole bunch of companies, and I didn't include them in a slide because I didn't have time to reach out and, you know, ask if they wanted to be included included in a slide and stuff, but we'll talk throughout the presentation about a couple of other organizations that are helping build the Mina ecosystem. Uh so this is our agenda for today. First we're going to talk about StarkyJS then the Mina protocol then we're going to do hello Wordle. This is a you know we'll we'll walk you through building a Wordle smart contract using StarkyJS. Uh and then we'll talk about next steps and have questions and answers.

So StarkyJS is a TypeScript library for defining uh zero knowledge proofs and it's also the smart contract language for the Mina protocol. Um it looks like this. We don't have to worry about that quite yet, but uh we'll talk about it in, you know, maybe 20 minutes. Everything is in Typescript, so you can keep using the tools that you're familiar with like npm, prettier, VS code with IntelliSense and ESLint. Uh and it's very easy to learn.

Um you can see here, uh we've done a pretty good job of making sure that everything in the library has really good typed do um coverage. So if you want to learn snarkyjs, you can, you know, do tutorials, attend a workshop like this, uh we have lots of recorded videos, but you can also just dive straight into a codebase and if you find something that you're not sure about, you can just hover your cursor over it and it'll probably give you a pretty good explanation of what it does, some example code, and then it'll, you know, of course explain the type as well. So snarky is easy to learn, but it's also exceptionally powerful. Uh and this is for two reasons. There's kind of two sides of this coin.

One is Kimchi, which is our proof system. Um this is kind of deep under the weeds. Uh you know, this is the the thing that actually makes the zero knowledge proofs and it has a number of features. Basically, it's state-of-the-art, but if you're into this kind of thing, if you're into cryptography, you know, these are some unique features that Kimchi has. It has fully trustless setup, meaning that you don't have to do any kind of ceremony in order to um create smart contracts or zero knowledge proofs.

Anybody who writes something in snarkyjs can prove it and they don't nobody needs to rely on this you know like powers of tow ceremony or something like that. Um it has custom constraints for poseidon elliptic curves and encryption. Uh so this allows you to do operations that you'll have to do frequently very efficiently. Uh it also has a constant proof size meaning that no matter how much computation you do the zero knowledge proof that you get out is always the same size and it's quite small. It's also recursive and this means that we can verify zero knowledge proofs that were generated uh using Kimchi inside of other Kimchi proofs.

Uh this when you couple it with a constant proof size means that you know we can have let's say five proofs each one is the same size and we can verify all of them inside of another proof and that proof is the same size as each of the constituent proofs. So this opens the door to a lot of really interesting things. And this recursion is not just sort of linear as in we can take one proof and put it inside of another. We can do arbitrary, you know, branch and merge operations kind of. Uh finally, it's plonkish.

And this again really just means that we're kind of like a part of an ecosystem of people that are developing uh new ideas and that we can utilize their new ideas as as you know the the whole sort of ecosystem works together. So again, this is not super important to dive into. Kimchi is not even a super important like thing to be aware of if you just want to build stuff. But if you're interested in the cryptography, you know, Kimchi is kind of like the cryptography engine that makes SnarkyJS work. So that's one half of the the power.

Uh again, this is what's under the hood. You don't have to worry about it too much. The other thing that makes SnarkyJS so powerful though is sort of the controls. It's it's the part that people actually interact with. Um you know as a developer you have to write stuff using this tool and we've tried to make it as easy expressive and powerful as possible for you.

Uh the method chaining API lets you think through your programs in a linear way. This is a pretty big deal compared to you know other zero knowledge proof programming languages where sometimes you have to think about things in sort of uh a way that I guess in a way in such a way that there's no concept of time. This tends to be very hard for most programmers today. It's very old school. Um, and so this method chaining API makes this pretty easy.

You can see we have something like uh let's do this one. Um, we've got this variable is not red peg. We've got a guess at an index. We can check if it's equal to zero and then uh, you know, not this. So we want to know if guess I is not equal to zero.

This is pretty straightforward. we check if it's equal to zero. If it is, we get a true. If it's not, we get a false. If it's true, then you know, we pass it into this knock and we get the opposite.

Um, and you can do this kind of over and over again. Uh, the result being that it tends to be pretty easy to think about, you know, here's my data, here's how it needs to change, and here's the output. And you don't have to worry about making sure that this is constrained too much. Uh, the other thing that we have is strct, and this allows you to define your own custom data types. Uh, this is again pretty unique to Snarky.

js. JS. Uh you can see up top here we have uh mystruct pure which extends strruct. Um uh actually let's do this bottom one. My tupil which extends strruct.

And so we can pick uh you know uh we can make an array here and have a public key and a string in it. And this is a new data type. So this one is very simple but we'll talk more later on about one that's more complicated. The idea behind this is that then once we have this strct, we can do whatever we like with it inside of our our um our smart contract and it just works. Um so yeah, instead of having to kind of worry about how your data is represented uh in in real time, we have this layer of abstraction that lets you, you know, define uh how you want to interact with things before you go about interacting with them.

Finally, plenty of the stuff that you need is already implemented inside of the Starky.js library. So what's included in SparkyJS today? Uh we have all sorts of types. Um unsigned integers 64 bits, 32 bits, integers of 64 bits, uh group, booleans, scale, um public keys, private keys, signatures, and circuit string.

Um and then with strrus, you can you know compose these to create even more complicated data types. Uh and we'll talk more about what these are under the hood in a little bit. We have efficient Poseidon hash function. Poseidon is a hash function just like you know kachac or something but it happens to be very efficient inside of our proof system. Um we have efficient encryption and decryption.

Uh we have efficient signatures. We have uh Merkel tree API, a recursion API and also an action reducer API. Sorry my watch just uh said hi. Uh okay so a common question that we get is you know why did we choose TypeScript? Lots of people have strong opinions about TypeScript.

Really the reason is because we're we're ecosystem focused. So the idea is that if you build uh userf facing products uh you can leverage other people's work to build these amazing applications that do things that you might not know how to do. I don't know like uh some kind of fancy cryptography thing. You might not know how to do like threshold signatures or or something like that. So the idea is that you know you can import people's code and and build these types of applications that uh depend on those primitives.

Uh and then if you are a cryptographer we have plenty of support to help you build the tools for other devs. Um so you can talk to people like me and things like office hours. U Mina Foundation uh has programs that can help you get paid to do this kind of thing. And the idea is that uh we want to have code reuse that's as high as it is in the JavaScript ecosystem. We want, you know, the people who want to work on hard crypto things to build hard crypto things and and be able to, you know, get paid for it.

And we want the people who want to build userf facing products to have doors open to them so that they can build kinds of products that were, you know, just simply not possible, uh, even a few years ago. Um, okay. So, how does it all work? Uh, here's kind of an overview of Snarky.js.

This is very high level. And at the end, if people want to dig in more with questions, we can do that or you can come stop me after. We also have again things like office hours. Uh so uh if some of this falls through the cracks it's okay. The idea is for people who are interested in how we take a javascript program and turn it into a proof.

This gives us a little bit of insight. So okay snarkyjest is a typescript library. This is here just to sort of indicate that it's not some kind of like was compiler or something. Um it's not taking your your typescript and compiling it into something else. It all is literally running in um node or electron or you know a chrome window.

Um it it is all literally TypeScript. Uh and so what happens is when we write things using uh snarkyjs it feels a little bit like react using JSX where we have this kind of like other syntax that's built on top of uh the JavaScript syntax that we're used to but it is all ultimately JavaScript. Um, and so how it works is we have a bunch of JavaScript types and then we have some snarkyjs types. Uh, and these snarkyjs types are all ultimately composed of this type called field. And what field is is it's an element of a finite field.

This is like a a math concept. It's basically a a specific set of numbers. Um, you don't have to worry about it too much. They're required for the underlying cryptography, but you have escape patches so that you can use, you know, like unsigned integers or uh strings, things that you're familiar with working with. But what you have to know just kind of like in order to orient yourself is that under the hood, everything is turning into this field type.

It's sort of like in a computer when you use a string ultimately it becomes, you know, an unsigned integer that gets, you know, represented as ones and zeros in in a physical processor. our sort of uh most fundamental uh representation of data is this field type. And so anything that we make in snarkyjs has to be able to be represented in this field type uh in order for us to prove things about it. And so what this means is that you know the normal JavaScript code that we write, JavaScript doesn't know how to turn something like a a a JavaScript boolean into a a field element. But the snarkyjs uh string type does know how to turn the the snarkyjs string into a boolean uh I'm sorry into a into a field.

Um and so snarkyjs provides classes and functions that are compatible with this field types or the strrus that are composed of them. Uh everything that we mentioned earlier uh unsigned integers um booleans whatever all of these are strrus that are made using the field type. And so you can make strcts of strcts so on. Um and so we have a bunch of classes and functions like one of these is you know circuit if one of these is add. Um they do the simple things you would expect but instead of doing these things on uh JavaScript types like numbers they do it on uh fields or unsigned integers that are composed of fields they do it on snarkyjs types.

And so snarkyjs can represent any operation on these field types as a kimchi arithmetization which is basically a math problem that uh mirrors what the program does. So the user doesn't have to worry about this. This is all done for you. You just write your program using the snarkyjest uh classes and functions and using the snarkyjs types. And as long as you've done this then snarkyjs afterwards can go on and introspect.

it can, you know, sort of look at the code that you've written and figure out how to make a math problem that'll check it. And then finally, uh, when a user interacts with the snarkyjs program, they can call a method and generate a zero knowledge proof that their interaction was legal. And this zero knowledge proof is basically doing some additional math to this math problem that we have that represents our our program and creating a proof or verifying the proof that comes out of it. Again, if this is kind of abstract or or goes overheads, that's all right. Come talk to me after.

Um, you know, there's a lot going on here, but all of it is is uh is under the hood. Users don't have to worry about this too much unless they're curious. Okay, so how does SnarkyJS smart contracts work? Well, the developers write smart contracts in Typescript and they deploy the verification key to a ZK app account uh on Mina, we have uh you know a bunch of nodes. Um we send a transaction, we sign it, and it has a verification key.

And this verification key is basically a number that's committing to the smart contract that we've written. And uh so that then later on the MNA network can verify transactions that are created for this smart contract using the verification key. And so if we were to change the smart contract code, the verification key would also change. Thus, if we say run a program correctly, but it's not the program that uh we committed to earlier, our proof just won't be valid. So yeah, the users run these smart contracts in their browsers or in node or an electron anywhere that JavaScript runs these will run uh and they generate a zero knowledge proof of their interaction.

So uh they take this zero knowledge proof and they send it to Mina uh and if the Mina blockchain can verify this zero knowledge proof then we know that the transaction is valid and it goes through and if the Mina blockchain can't verify the zero knowledge proof then we know the transaction is is invalid and it it you know just gets dropped. Yeah, of course. Yes, Mina only needs the key. So the circuit can live anywhere you can put it in. Um okay, so I'll restate the question for everybody.

So the question is how does the Mina blockchain get the the circuit? Um or I guess like the the program the Mina blockchain only has this verification key. Yeah. So the Mina blockchain has the verification key and this commits to all of the functionality of the program that we wrote. The program itself can live anywhere.

It can live um on like a content delivery network. Uh it can live on IPFS. It can live even on something like Ethereum. Um it really is just TypeScript code. Uh and as long as you can get a hold of it and run it, uh the the Mino blockchain doesn't even have to know what the code does.

It just has to have this commitment to what the code does in order to be able to to check uh that you ran it correctly. So the the code actually does not go on the blockchain. it just lives wherever you want to put it. Um, the only thing that has to exist on the blockchain is this verification key that's used to verify um that the code ran correctly. Does that answer your question?

You are in charge of the code that's used to generate the proof uh that then the Mina blockchain can verify using the verification key that's stored on the Mino blockchain. Oh. Uh, when the user sends their transaction, they're basically specifying the Yeah. The same way the same way that you know like when you call an Ethereum um uh smart contract, you are uh specifying an address and then also a uh you know a specific method. Um the same thing is basically happening with Mina.

You're specifying which account you want to create a transaction for um which smart contract you want to interact with. And so that's how it knows which verification key is tied to your code. We can also come back to this later on if you want. So uh okay let's jump back into this. Sorry.

So if the Mina blockchain can validate uh the zero knowledge proof then it commits any relevant state updates. Let me jump back one. Uh okay. So yeah if the Mina blockchain uh can verify the zero knowledge proof then it will commit any relevant state updates. So when we do something we usually want to change the state of the world.

we want to uh you know update a value, change somebody's balance, change a permission, something like that. Uh and so when we run our smart contract method, we get a list of things that we want to do, uh a list of states that we want to update, etc. And we also get a proof that says we're allowed to update these states. Uh and so we send just the proof and uh these updates to the Mina blockchain. And if the Mina blockchain can verify the proof, then you know, uh we do these things.

And so we pass into our smart contract uh some arguments you know that the user provides the state of the smart contract at the time that we're running it and the user can query this from the Mina blockchain um and then also some values from the state of the world. This can be something like block height. Uh what we get out is a proof that we did this correctly and we also get updates to the state of the smart contract and updates to the state of the world. All right. So that's how ZK smart contracts work.

But how do ZK apps work? Uh it's pretty simple. You can just install your smart contract into your UI repository and deploy it. So uh yeah, you can publish it to GitHub, you can publish it to npm as a package, whatever you want. Um and then when it comes time to use it in your UI, uh it's just TypeScript code.

So you just import uh the smart contract methods that you need to call strictly into your front end. You know, uh then the user does something in your front end. the front end calls the the um the appropriate method in the smart contract and uh creates a proof and then we send this proof off to the Mina blockchain. So all of the code runs in the front end and the only thing um that uh lives on the blockchain is this verification key which is used to verify that we ran the code correctly in the front end. Okay, so now let's talk about the Mina protocol.

Uh what is Mina? Uh it's a layer 1 blockchain that proves its entire finalized state using recursive zero knowledge proofs. So other blockchains increase in size as more transactions are added. Um a blockchain like Ethereum uh needs to remember every single transaction that's ever happened in order to be able uh to verify that transactions that have happened recently happened correctly. Um so as time goes on, Ethereum scales not only with the number of accounts that people are um in control of, it also scales with the number of transactions.

Uh Mina does not. It stays 22 kilobytes a fixed size. And uh and so we can get into a little bit of what this means. Um basically Mina does not have to remember uh all of the historical state. Uh and the reason why is because instead of using uh you know this kind of a bunch of signed transactions and then a a pre-agreed uh way to you know evaluate these transactions um and then a bunch of game theory because we do them all in the open and remember all of them.

Uh Mina uses cryptography directly uh to verify these uh transactions. So it uh it uses zero knowledge proofs instead of uh game theory. So is this just cool or is it actually useful? Uh the answer is that it's both. Um and for quite a few reasons.

Uh the first is privacy. Uh so on Ethereum smart contracts run on every single node. And so all of the information is inherently public. Uh if we have an Ethereum blockchain here and an Ethereum smart contract and we want to call a method, we call the method. we specify uh the arguments that we're passing in and then we send basically this call and uh and the methods uh I'm sorry and the arguments that we want to um to pass in to every single Ethereum node and every single Ethereum node evaluates these in public all at the same time.

And so this means that it's very hard to build private applications on Ethereum. If you want to build private applications, you have to find a way to obfiscate uh data that's inherently public to such a degree that it's effectively private. Um, and this usually involves really complicated cryptography. So, Mina smart contracts run in the browser. Uh, and this means that the arguments and the intermediary values are private by default.

Uh so if we want to run Amina uh smart contract method, we call the method and we pass in the arguments on our local machine and what we get out is the relevant updates as well as a proof. And so we send just this proof and the updates to the Mina blockchain and uh Mina will verify the proof and then update the the state onchain if the proof is valid. Uh and so this proof doesn't disclose any information about the computation that we've done. Okay. So uh we have privacy and we also have scalability.

Uh there's no gas model. Um ZK apps run offchain and so the amount of computation doesn't affect the transaction cost. If we do a lot of computation, it might take a little bit longer for our browser to you know run the method and generate the proof. But uh the proof that we get out will be the same size and the same computational complexity to verify. So uh if we want to do a tiny bit of trans uh a tiny bit of computation that works and if we want to do a ton of computation that works we just might have to wait longer but it'll you know be on the user's machine.

Uh once the proof goes to the blockchain it will always take the same amount of time to verify no matter how how much computation you do in it. So you can actually do an unlimited amount of computation in a Mina transaction. Um and in fact the Mina blockchain itself is kind of an example of this. We're doing basically an unlimited amount of computation and attesting to the fact that it's correct using this single proof uh which is tied up in this you know 22 kilobytes that we talked about earlier. Okay, so this works great if you have transactions uh that do a lot of computation but what if you want to build applications that do a lot of transactions?

Uh in this case it's possible for developers to use recursion to build uh these things we're calling application specific roll-ups. And these are basically what they sound like. Uh if I have something like a game, let's say I have a two-player game and I want to play this game um uh in kind, let's say I want to build this game in like the most naive way possible, I would build a smart contract where when I want to make a move, I call a method and when you want to make a move, you call a method and we go back and forth like this. This works fine. This is how everything works on every other blockchain right now.

But uh the problem is that we have to wait for a block to be mined and we have to pay a transaction fee every time we want to make a move. With Mina, this can work much differently. Uh because the the smart contract execution is verified using cryptography instead of game theory. Um we can have the whole blockchain validate, you know, some computation, but in many cases we don't have to. In the case of something like a two-player game, the only person who really needs to check that I'm playing the game correctly during the course of the game is my opponent.

Right? In theory, they should have an incentive to to not let me cheat. If they do let me cheat, then the game is pointless. So, what I can do is I can actually write the smart contract in such a way that I make a move, I create a proof that my move was valid, I send my opponent the proof, they verify the proof, and then they make their move. And when they make their move, their um computation for their move will actually also verify the proof of my move.

And so you can go back and forth this way, exchanging uh these proofs. And the proofs don't grow, right? I send you a proof of a fixed size. You make your move and send me back a proof of fixed size that attests to your move and my move. And then I make another move and now we have a proof that's still the same size, but it attests to three moves.

And we can do this over and over and over again until eventually we reach an end state. And once we have, you know, a complete game, a proof for a complete game, then we can actually send this into the Men blockchain and pass this proof as just an argument to uh a smart contract method. And so we can pass a proof that says, "Hey, I won. Let's pay out uh I don't know, some reward to to me." Um so yeah, there's a lot of other ways that you can kind of extend this model.

Uh this is fairly complicated and actually this is just the very beginning of a sort of series of workshops that will explain how to build um an Amina application from you know nothing to uh something that's pretty polished and uh you know has sort of touched all the bases so to speak. Um so we'll talk much more about this. We'll actually have a session of this workshop. Um so the the subsequent sessions will be remote. You can watch them online.

uh and we'll have a uh a follow-up session that will talk about how you can build an application specific rollup for the Wordle game that we're going to build today. Okay. So, uh we have privacy and scalability. Usually, uh these come at this cost of decentralization. Uh however, for Mina, this is not the case.

Uh because it's possible to validate the entire finalized Mina state using only a small zero knowledge proof. Uh and I'll kind of maybe touch quickly before we jump in anymore on why this is possible. Um so the way that Mina works is that we have uh a bunch of transactions and these transactions are zero knowledge proofs and then we have our consensus mechanism and this is something that we can also prove using zero knowledge proofs. And so what we do is we take a bunch of transactions that are zero knowledge truths and we verify them and we also verify that they have um been sort of processed correctly that states and stuff have been updated correctly. Uh and so we have all this computation of verifying the proofs and doing the things that the proofs tell us to do.

And we can verify all of this information in another proof. And then uh when it comes time for us to do more stuff, you know, when we have more transactions, we can take this last proof, verify it, verify all the transactions and verify that we've done everything correctly and create a new proof. And then we can forget about the last proof. And so in order to know that the current uh finalized mean estate is correct, you just need to verify this single proof. Um what that means is that uh you can verify this proof kind of anywhere.

It's pretty easy to do. It doesn't require a lot of like storage or networking overhead. Um and the end result of this is that there's not really a reason to rely on on trusted third party node operators. Um this is another uh team in the ecosystem. Uh they are called um uh viable systems or viable labs I forget.

Um but they're working on something called open mina. Uh there's actually a demo of this that exists today and it's linked to at the end uh with this QR code. So what is this? This is a full Mina node that runs in the browser. you can go to this website, send a transaction today without connecting to, you know, any kind of like RPC endpoint.

Um, literally everything happens in the browser. We, you know, start some stuff. We, uh, get it all ready. We connect to some other nodes and then we catch up to the network. Um, and this all happens in less than a minute, and then we're ready to send transactions.

So, you can imagine this can be built into uh, mobile applications. It can be built into um browser plugins and it can be built even directly into websites themselves. Um we hope that this will result in a network that is substantially more decentralized than uh anything that really exists today. Um it's quite a different way of doing things. Okay.

So if Mina is so yeah go ahead. Yes. Okay. This is a good question and also uh yeah I'll just say ahead with anybody that has questions jump in. Usually these presentations are a little bit sort of smoother but this one the idea is that um uh yeah the idea is kind of that it's pretty hands-on and and anybody who has you know we'll kind of talk about whatever people are curious about.

So we talked about these nodes we talked about 22 kilobytes. So um what is this 22 kilobyte thing? What it is is it's the proof for um it's the Mina proof. It's the state root of Mina. So we have a Merkel tree that you know is committing to all the data and we have a root of this Merkel tree.

Um and so the the the proof basically says that this Merkel route is correct. The Merkel route attests to all the information downstream of it. And then what we also include in this 22 kilobytes is a path down to a single user's account and all the information that's stored in it. And so what that means is that with 22 kilobytes we can store um everything we need in order to know that Mina is working and we can store all the information that's relevant to ourselves. So what that means then is that if I want to go talk to you know somebody like you and send you a transaction well you have all the information for yourself, I have all the information for myself.

We both have all the information for Mina. We can construct a transaction um to let's say do something simple like transfer funds between each other. That's what the 22 kilobytes is. And so this is all that's needed for something like um one of these web nodes that we looked at earlier, right? It's only concerned with one account.

There's another kind of node called a block producer node. And this type of node records the state of all the accounts, but it doesn't store any history. And so the reason that it doesn't store any history is because it doesn't have to. It um it knows that all of these states are correct based on, you know, the the zero knowledge proof. it doesn't need um to be able to sort of like sum up all the historical transactions in order to know that the state where that we're at today is the correct state.

Um so these block producer nodes are named uh accordingly. They're able to produce blocks because they know everybody's state. Um these nodes grow based on the number of accounts. They don't grow over time. Um, and so what that means is that there's kind of like a, you know, there's a place where it plateaus.

There's a point in time where people don't need more accounts. There's a limited number of people. Even if they're interacting constantly, we can forget about the history of their interactions. And so these block producer nodes are still very small. They're a couple of gigabytes.

You can start one in less than an hour. Uh, and you can be producing blocks. And they won't Oops. Hopefully it comes back. Yep.

Okay, we're good. There we go. Um, uh, okay. So, we have block producer nodes. Uh, the final kind of node that we have is called an archive node.

And this does what it sounds like. It, uh, stores, uh, every single account and the history for every single account. These are useful for things like block explorers, um, you know, uh, people who want to do like analytics, um, that kind of thing. And so these block producer nodes um store everything and expose it all through uh a GraphQL. Um so hopefully that answers the question.

We have kind of three kinds of nodes. Um one node has everything you need for a single account. Another kind of node has everything you need for every account. And a third kind of node has everything you need plus all the history of everything that's happened. I will continue to jump forward then.

Okay. So, if Mina is so easy to verify that we can do it in a browser, uh, can we do it in other places? Could we do it in like a smart contract, for example? Um, I'll get to you in just a second. Uh, because Mina is so easy to verify, it's actually possible to write smart contracts on other blockchains that can verify the Mina state proof and as a result bridge the entire Mina state over to, you know, their ecosystem.

Um so yeah, smart contracts on other chains can bridge the whole Mina estate just by verifying the most recent proof. We have another um uh found uh we have another organization in the ecosystem that's working on this. They're called the nail foundation um and they're building in EVM minate verification uh and also a bridge to EVM chains. Uh so there's also a demo of this live. A lot of this stuff is very close to to finished.

Um and so what we can do is we can take the you know information from Mina this is going to be the state route the the um the proof etc. And we can uh build an auxiliary proof which is just a proof that's more efficient to verify on on Ethereum. Um this takes maybe a minute on a MacBook Pro. Uh and so we get our auxiliary proof and then we can pass this auxiliary proof as an argument into a uh smart contract on uh another blockchain. In this case we're using uh Polygon Mumbai but you could do just as easily on Ethereum.

Um and so we send this transaction and uh the transaction gets mined. Um you can see it costs 9 cents on uh Polygon. Um and uh the end result of this then is that the whole entire Mina estate uh or a commitment to the entire Mina estate is bridged over to um this uh blockchain. So now people who have smart contracts running on polygon can um you know if they want to access some uh value from a mina smart contract they can uh basically you know uh pass in the merkel proof down to this um uh chunk of information that they want from the mina smart contract. Um and then you know uh verify that this is valid according to the state route that we have um in our in our bridge contract.

And we can interact with this information on Mina. Um this is yeah a much different way of bridging uh because it doesn't require any sort of like locked you know capital or anything. It's instantaneous as soon as we pass the proof in and the contra the transaction is mined you know all the information is bridged over and also anybody can do it. So you can have sort of a situation where um you know if I have some sort of arbitrage or something I want to do and I want I have an incentive to update the information to the most recent um uh values I can just call this method uh straight before I I I do my arbitrage or something. Uh so there's the answer is that this will also include the time stamp.

Um, so the the Mina smart contract will I'm sorry, the smart contract on uh Ethereum will also have um uh the time stamp for the I'm sorry. It'll have the block height for the Mino blockchain and no, I'm sorry. I meant to say block height. Well, no. So the the block height would have to be higher than the last uh than the than the last block height that it verified.

Okay. Sorry. And then I'll also get going a little bit quicker um just because I've realized uh we're behind a little bit. But uh somebody back here had a question. I'll answer very quickly.

And I'm also going to take a drink. I think it isn't. Oh, it is. Nice. Hi.

Hey. Thank you for telling us all this stuff. Of course. So, I think I understood now that apart from this very small proof, there's a state somewhere. Yes, the state lives on uh the Mina block producer nodes.

Um but it's also not coupled to um this is something we should talk about. I'll talk more about this at the end. The the state is not sort of inherently attached to the computation in the way that something like Ethereum requires that it be. Um so the amina nodes can store state but you can also put state somewhere else like for example if you wanted to have a lot of your state stored uh like on the user's like machine locally. Um you can do that too and you can just have your smart contract um store like a Merkel route that's committing to all this state.

Um so so I could have my own node running in the browser and publish my proofs but never publish the state. Yes. Well, so um it depends on what kind of So the the block explorer, no block explorer could analyze my transactions because I never publish them. You you can do this but not um there is state that's stored directly on Mina. Uh so you could do something like this.

You could have a state that's stored directly on Mina be used to store a Merkel route for a bunch of private state that you could store yourself and then the Merkel route will not reveal any of this private information. Um, and then you can do what you want to with this private information uh and prove that you're altering it, you know, that you're augmenting the information in ways that are allowed according to some set of rules that you define in your smart contract. Um, and then, uh, as you make these changes, the Merkel route will update, and so you'll update the Merkel route on chain, but the Merker route won't reveal any of the information, um, that you're storing locally. Does that make sense? I think it does.

Yeah. But I cannot like transfer Mina without exposing who is part of this transfer. This is true. um in like this is true if you don't build anything in addition to what we've built. Uh but because it's so easy to use zero knowledge proofs with snarkyjs on Mina, it's very easy to build um mechanisms that would allow you to do something like shielded Mina transfers.

Um yeah, and so that's we can talk more about this. Basically all of the state is public by default but it's very easy to use this state to commit to private state. Um yeah and so the state has to be public uh right because it it's um otherwise you can't come to consensus on it. The key is that the computation can be private and so this opens the door to yeah all sorts of stuff but I'll I'll jump back to this at the end. For now I'll kind of keep going forward.

Soles because snarkyjs smart contract methods can accept and validate uh signed data and because this happens on your local machine um it's possible to ingest verified data privately. So this means that like if I have some service that will provide me with a signed credit score or something um I can grab this from that service and I can pass it directly into my smart contract. Uh this also means that it's possible to ingest a lot of it. You can ingest rich data using uh snarky.js.

Um so as opposed to having like an oracle that stores like the price of a token or something, you can dump a whole um uh a whole like JSON response into a smartyjs smart contract. In fact, we have uh uh I guess a a friend who's working in the ecosystem who's built a uh a um a uh JSON parsing library. Um okay, so we can ingest data privately and we can also ingest a lot of it. Um and in the future, ZK oracles will allow users to verify data from uh any HTTPS website or API. So right now uh you have to have you know somebody sign this data.

This can be the person who's providing you the data. It can be some sort of trusted uh middle party. Um but in the future, it'll be possible to basically uh grab any data from any website or API that's returning the data through an HTTPS connection and uh verify that this came from the the domain that you know claims to have sent it. And then we can pass that information into a into a smart contract. So, we can do something like go to a website, grab a value that we want to pass into a smart contract, and then pass it in in a provably uh sort of uh correct way.

Okay, what else do we have? Uh well, we actually don't know everything that's possible yet. And so, that's why we're hoping that people like everyone here, you know, build cool things, talk to us. Um and yeah, we've we're kind of building the foundation and hopefully opening a lot of doors. Um, and we're we're excited to see what people end up doing with it.

Okay, so uh now we have our hello worldle part of the presentation. We'll uh talk about a smart contract and build it together. Um, so if you haven't yet, uh, install NodeJS and npm, uh, npm install-g u, the zcap cli uh, and um, and clone the github repository. Um, for people who don't know, uh, Wordle is a game where there is a secret word and we try to guess what the word is. And when we make a guess, we get gray tiles if we've guessed a letter that's completely incorrect, as in it's not the correct letter and it's not in the correct place.

We get a yellow tile if we've guessed a letter that is in our word but is not in the correct place. And we get a green tile if we've guessed a correct letter in a correct place. And so we have a limited number of turns to try to guess what the word is um by sending a word, getting some hints in a response, and then guessing another word, and so on and so on. And so here we guess uh bears first. Um we can see that R is a correct letter, but it's in the wrong place.

Then we guess uh group. We can see that now R is in the correct place, O is in the correct place, O is in the correct place, and F is in the correct place, but G is not in the in the word. And then eventually we guess proof. and uh and that's the the right uh word. So, we get all green tiles and we've won the game.

So, there's a few things to keep in mind for this. Uh the first is that this is generally played as a oneperson game, but in this case, we're going to build the smart contract um for two players. And one player will be the the sort of the word guesser, the standard player, and the other player will be a hint generator. And the reason why it makes sense to have two separate players for something like this is because uh the if you were to build this as a oneplayer game, your machine would have the secret word in it basically and so you can you can find out what the word is, right? Um like in other words, your browser would contain uh the word that you need to to guess.

Um, so it makes sense to build it as a two-player game and then if you want to play it as a one-player game, you would have a third party. It could be a service um that would play the game against you. So, uh, for this, we're just going to build the smart contract. The rest of the app will be coming soon. Um, and we'll have, like I said, another um another workshop on that later.

Um, so we'll talk about the structure of the smart contract really quickly. uh and you can open up the um uh source uh Wordle strruct um file on your computer if you're interested in following along. Um first we have kind of like a preliminary thing and so don't worry too much about this. Uh this is defined at the top above our smart contract. Um and this is a strct.

Uh so we're creating something called word by extending strruct. uh this thing called word uh stores um encoded word which is an array of five field elements and so we've defined uh a way to store um one of these word words um using field elements. Now what we also have is a static method from string which we can pass a JavaScript string into and when we do that we'll convert that string to be all lowercase. we will um increment through each value in the string. We'll use this regular expression to test if it's a letter uh and if it is a letter then we will push this onto our encoded word array um as a field.

So we'll take the character code for the word minus 96. This just gets us um you know values between 1 and 26 uh for the letters of the alphabet. uh we pass this into field in order to create a field of this um of this value. So we're passing a JavaScript number into the field um and we're getting a field of the same value and then we're pushing this onto that encoded word array. Um if the letter is not lowercase um or if it's not a letter, if it's like an amperand or something, then we just push a one value which is an a character.

Uh then finally we return a word um that includes our uh encoded word that we just created. So what that means is that we can call you know word uh dot from string pass in a string and we get back a word that represents it. Uh we also have this other method here hash and hash will return um the hash of this encoded string. So you have this Poseidon uh function um I'm sorry we have this Poseidon uh object um and oops I'm sorry about that. Um, let me make sure that does not happen again.

Okay, so we have this uh hash function um and we're going to pass in our encoded word. Uh, the hash function accepts an array of fields um, and out we get a hash which is a single field element. Uh so we've made a strct that's going to make it easy to work with words in our smart contract. Um it takes JavaScript words and represents them as uh field elements. Now we'll talk about the structure of our smart contract.

So we have um this thing smart contract and we extend it into Wordle. So we've now created a smart contract called Wordle. And the first thing that you'll notice is these three uh state decorators at the top. These are used to tell Mina that uh these are variables that we want to store in the state of the Mina blockchain. We want Mina to basically uh store these in the blockchain and then check that when we're updating it that we're that we're updating them in in a valid way.

Um and so we have one called solution hash. This is a field element. Um, we have one uh and yeah, field elements. I think I mentioned this earlier, but they're basically for uh when you're kind of just getting started, they're really the same thing as as unsigned integers. There's a couple interesting properties that they have, but they're very similar to numbers you're used to.

One of the properties that they have is that you can't really uh the you can't really like call like a a mod method on um a field element. It doesn't make sense. There's not like a way to do modular. They're kind of inherently um doing this already. So in this case, we have a turn number and we want to be able to check whose turn it is by, you know, uh turn number mod one.

Um, and so we use this unsigned integer of 32 bits. Um, and this is again under the hood comprised of a field element, but it has some extra logic that allows you to work with it just like you know you work with the unsigned integers you're used to. Finally, we have this word object what we def uh sorry, we have this word type that we defined earlier uh using the strct. Um, and so this will represent um uh the last guest that we we uh made and it will also store the hints that the user creates. I'm sorry that the hint generator creates.

Then we have an init method. This is a method that will run um before users interact with the smart contract and we'll talk about that in a second. Uh we have a publish guess method which will take in a word uh as an argument. So this does what it sounds like. we call it when we want to publish a guess.

And then we have a publish hint method. And this uh also will take in a word. But this word won't actually be the guess. It'll be the secret word. And it's okay to pass in uh a secret word as an argument to uh to uh this method because, you know, it won't ever uh actually leave your machine.

Uh finally, we have yeah, I'll kind of talk briefly about what these decorators are. Um, this method decorator basically tells SnarkyJS that this is a method that users are going to call. The state decorator basically tells SnarkyJS that this is a state that should be stored on the blockchain. Um, so these uh these decorators are a part of TypeScript. They um I think that it used to be called atcript.

I think that this used to be in two separate projects. Uh, but these are just like Python decorators. Um, I can talk more about them with you after if you want, but what they basically do is this says this tells JavaScript, hey, take this, pass it into a function, and then whatever comes out of that function, put in place of of this uh chunk of code. Okay. Um, yeah, I I think that's a good way to characterize it.

Yeah. Um, okay. So, we've got this init method. I said earlier that this is something that we'll call before users interact with the smart contract. Um, we have, uh, super init.

Don't worry about that. That does what you'd expect. Uh, and then we have, um, some initialization. We want to set all of the variables, you know, all of the state variables that we defined earlier to initial values. And so, this init method should be called before any user interacts with the smart contract.

In other words, immediately after deploying the smart contract, we should call this init method. Um, and so when we call the init method, we will take this solution hash and we'll call this set method on it. And what we'll do is we'll set it to a word um from string hello and then the hash of that. And so we take our word hello, we generate a word from it. We get the hash of that using this hash method that we defined and then we pass that into set for this solution hash.

Um, and what that does is it sets the solution hash on the Mina blockchain equal to this value. Next thing we want to do is set the turn number to zero. So we'll create a new unsigned integer of 32 bits. Uh we'll set it equal to a field um which is uh equal to a JavaScript number um that's zero. Uh so we'll get you know basically JavaScript 0 turns into field zero.

Field zero turned in turns into unsigned integer zero. Um and then we set this to turn number. And then finally, we'll set the initial guess. Um, and so we'll just make it a a aaa. Uh, and it won't be possible to generate a hint until the guesser updates this.

Um, so it doesn't really matter what this is. We're just initializing it. Um, I guess cuz it's it's, you know, good practice. Um, so we do the same thing. We get a word from string and set it equal to uh last guess.

So again, this method should really only run once, right after the smart contract is deployed. and then nobody will run it again. Next we have uh publish guests and so we'll talk about what this is going to do like how do we do this. Um the first thing that we want to do is grab the turn number from the Mina network. So because our smart contract runs locally we need to you know grab the the number from the network before we can do things with it.

Uh the next thing that we're going to do is we're going to check that it's the guesser's turn and so we can use the turn number to check if it's our turn. Uh after that we will increment the turn number. Uh then we'll check that all of the values that we passed in in our guess word are between 1 and 26. In other words, that they're valid letter configurations. That way we can't guess a word that the hint generator can't generate a valid hint for.

And then finally, we'll set this last g this last guess state to our new guess. So first things first, we'll grab the turn number from the Mina network. So we'll make a variable turn number and we'll set it equal to uh you know uh turn number get. This get method will uh yeah contact the MN network grab the value for turn number and then we'll we'll dump it into this uh local variable. The next thing that we'll do is we will assert that this turn number that means the the turn number variable in the Mina network is equal to turn number in our uh local runtime.

And so this line is kind of interesting. It uh is necessary because the smart contract runs you know outside of the context of the blockchain. So what that means is that let's say that we were to do something like grab a turn number um you know run this method grab a turn number at one point in time and then wait like a day and by that time the turn number had changed somebody else had changed it. Uh well then our proof is valid but it's not valid for the current time anymore. Does that make sense?

Like it's valid assuming a precondition that is no longer true. And so what this assert equals does is it checks that this condition is true at the time that the the proof is accepted. Um so in other words, this top line grabs the number and does stuff, you know, it grabs the number at at runtime. And then this bottom line checks that the number that we used at runtime is the same as the number on the network when it comes time to verify the proof. Yes, that's correct.

Yep. Um, okay. So then what we'll do is we'll check that it's the guesser's turn. So we'll take turn number. This is our unsigned integer.

We have this mod method for it. Um, we'll call mod 2. So we'll get uh, you know, I think um, uh, zero if the turn is uh, even and one if the turn is odd. Uh, I might have got that backwards, but then we'll again we'll call this assert equals method and we'll pass in uh, an unsigned integer that's uh, of value zero. Um and so this assert equals method basically uh what it's doing is it's uh it's saying that unless this condition holds true unless turn number mod 2 is equal to zero uh it should be impossible to generate a zero knowledge proof.

Um and so in this way if we try to run this method on uh the the wrong person's turn uh what we'll get is even if we can run the method locally we will not be able to generate a valid proof for it. The final thing that we'll do is we'll increment the turn number. We'll call this set method. Does the same thing as it did earlier. Uh and we'll pass in turn number, but we'll add to this turn number uh an unsigned integer of value one.

Um and so the turn number will be incremented. And then uh we will check that all the values are between 1 and 26. So we just have this for loop. Um we're going to grab you know guess. Um so this is our our word that we passed in.

We're going to uh uh grab values um from this encoded word uh and then we're going to call the assert method on them. So these values will be fields and the field type has this assert uh greater than equal to less than greater than or equal to etc methods attached to it. And so we can assert that it's greater than or equal to one and less than or equal to 26. And we'll do this for each uh index in the array. And the result then is that we know uh again if we find some way to pass in a value that's not really a letter, a value that doesn't make sense, it just won't be possible to make a proof and so we won't be able to update uh the state.

Uh the next thing that we'll do is we'll set last guess to the new guess. So this is pretty simple. We've got our guess. We've checked that it's our turn. And now we can set the guess um uh um on chain.

So we'll take our last guess and we'll set it equal to the new guess that we passed in. So that's one half of the interaction. This is what the the guesser does. Now the other half uh is what the hint generator does. And this is a little bit more complicated, but it's basically the same idea.

Uh we have um this publish hint method. We pass into it a word which is our solution. It's actually the secret for you know it's it's the solution word for the game. And Um the top part of this is very similar to what we've done before. We're going to grab the turn number from the Mina network.

Uh same thing as before. Turn number get set it equal to a variable called turn number. Assert that the turn number that we use at runtime is equal to the turn number at the time that we validate the proof. And then we're going to add one uh and mod to check if it's the hint generator's turn. So we'll take the turn number we'll add one we'll uh you know mod two and it should equal zero right the idea being that um uh this is the opposite of what we checked earlier um by adding one uh we are um checking that uh it's um we're we're checking you know this will be true only in cases where the the the similar chunk of code for the other method would be Um so yeah this is is doing the opposite of what our turn number check did uh for the uh publish guess method.

Um so that we will only be able to run this method if the the guesser has just guessed but the hint generator hasn't generated a hint yet. Uh the final thing that we'll do is we'll increment the turn number again. Uh same thing as before we take the turn number we add one to it uh and then we set it uh on chain. Okay. So what do we do then?

Uh we have to check that the solution that we provided you know that we passed in as an argument uh is correct right this we want to keep it private. So we don't want to store the solution on chain but we still want to be able to check that we're not changing what the solution is every time that we uh you know generate a hint right because you could make the game unwinable that way. So what we do is we grab this solution hash that we stored on chain and this is a commitment to the solution that doesn't reveal what the solution is. um and we assert that the solution hash is equal to uh the solution hash just like earlier. So we check that uh the value that we grabbed um when we run the code is the same as the value that exists on chain when we validate the proof.

And then what we do is we check that um the solution hash is equal to uh the result of calling the hash method on our solution that we passed in. Um, and so now we know that uh from turn to turn uh we're not changing uh the solution. In other words, we're always passing in the same solution value um uh because we can check it by uh hashing it and then comparing it to the to the hash that we've stored on chain. So all of this is is checks. We're checking that it's our turn.

We're checking that the solution that we provided is valid. Um, and now we can actually uh grab the last the last guess, the guess that the the last player um submitted. Uh, again, this should look pretty familiar. This is basically the same thing again. Um, and we can actually go through the process of generating the hint.

Now, you know, this is the most complicated interesting part. Um, and so first we want to check if we have any green hints. You know, we want to check if there's any green letters. These are letters that are the correct letter in the correct place. What we can do is we can uh have this for loop that that runs through uh every uh index in the array and we're going to check if the letters at this index match.

So we have is correct position. This value will be a boolean um a sarkyjs boolean um and it will um uh be true if the value in last guess at index i is equal to the value at solution in index i. Uh and so this equals method is different than the assert equals method. The assert equals method just makes it impossible to make a proof unless it's true. Uh the equals method returns a one or a zero.

it returns a boolean. Um so uh if the guess and the solution have the same letter in the same place then this will be set true otherwise it will be set false. And so if the letters match then what we're going to do is we are going to add 200 to the letter. This way we still keep basically a representation of what the letter is, right? Because it's a value between 1 and 26, but we get a two in front of it.

If um if it's a correct uh if it's a if it should be marked with a green hint. Um the idea being like if we have Z and Z is correct, then we'll take this 26 and we'll increment it to 226. And so then the you know the the the um the guesser can look at this and say, "Hey, uh this is a Z and it it is a correct letter in the correct place. we got a two. Um, so what we do there is we use this circuit if method and we pass in is correct position.

So this is true or false. If it's true, then we add 200 to this uh value in the uh in the in the last guess. And if it's false, then we just set the last guess equal to what it was before. In other words, we do nothing. Yes.

if it's okay. Do you mind? I think I only have a couple minutes left. So, do you mind? We'll we'll go back to at the end.

Sorry about that. Okay, so we've got our green letter hints. Next up, we have to check for our yellow letter hints. These are hints that are going to be for letters that are included in the word, but were not uh guessed in the correct position. So, this time we have a nested for loop.

Uh we're going to iterate through every value in one word. uh the guess and every value in the solution. Um and so what we'll do is we'll check if the letters at these indexes match. If they do match, we'll you know set does letter match equal to true. And then if the letters match, we'll also add 100 instead of 200 this time to the value.

So um this is the same thing again. Uh we have our our last guess. Uh if the letter matches, we add 100 to it. If the letter doesn't match, we set it equal to itself. But in order to not count the values twice, what we have to do is um set the values in the solution to zero.

Um the reason being uh that this way we only count the correct uh number of letters in the wrong position once. Does that make sense? Otherwise you would iterate through and count them multiple times. So we want to sort of like check off that we've already counted um that these letters match after we've done so. And so this time what we do is we have the same thing but for solution and we uh use this uh circuit.

Uh if the letter matches we set this solution value equal to zero otherwise we set it equal to itself. And so the idea then is that if we count the letter then we set the solution value equal to zero. So that then we can't count that letter again. Um because you know zero represents nothing. It doesn't represent any letters in in this case.

Um and so nothing in the guess will match it. we check to make sure that the guess doesn't have any zeros in it. So once that's done, what we get is we get uh this last guess. Um and now it has values that either equal the same thing that we passed in um you know so like one would equal 1, five would equal 5 or it has values where five has turned into say 105 uh or you know 12 is turned into 112. meaning that this letter is a correct letter, but it's in the wrong place.

Or um if uh if we um have a correct letter in the correct place, then we've added 200 to it. And so we get uh you know, 10 would turn into 110 if if we guessed uh that, you know, uh if if that letter was a correct guess uh in the correct place. Okay. Okay, so the final thing that we do is we take our last guess and we set it equal to um um sorry we take last guess on chain and we set it equal to the last guess that we just generated. And so what this does is it updates all of the hints on chain um so that then the user the guesser can go and look at the hints and check whether um you know they got any correct you know whether they got any green or yellow hints and then they can use this to generate a more informed um next guess.

And so this exchange goes back and forth until either a turn number is hit which we didn't implement here just for the sake of simplicity or until the user generates um uh until the user guesses the correct word. Okay. So now we can test it. Uh what you can do is you can save your file uh and you can run npm run test. And when you do you should see something that looks like this.

Uh you can see on turn number one we are going to guess the word exile. This means that we're going to set guess equal to 5 24 9125. That represents exile. You can see E is the fifth letter in the alphabet. And this last guess starts with five and ends with five.

And then we increment to turn number two. And we'll guess um you know exile is still the word that we guessed, but this time uh we've taken uh five and we've incremented it to 105 because E is a correct letter, but it's in the incorrect place. We can see that we've taken L which is 12 and we've incremented it to 212 because L is the correct letter in the correct place. And you can see that five has not been incremented. We did not count it twice.

Um so even though there is an E, there's only one E. So uh this stays five while the first one increments to 105. So now let's guess hello. Uh this is the correct word. So we'll take this value, use it to uh determine what we should, you know, guess next.

Um, we can see, hey, hello's got an E in it. It's got an L in the right place. Let's try hello out. So, we encode hello as 85 121215. Uh, and then, um, when it comes time for the hint generator to look at it, every single letter is in the correct place.

So, we get, you know, 208, 205, 2012, 212, and 215, meaning that we've guessed the word correctly. Okay, that's that. Uh, congratulations. you've built just built your first CK app. Um if this seems you know maybe not so satisfying that is why we have um uh we will have um more uh you know remote presentations in uh like a live stream form uh that will explain how to build the front end for this.

how to build um a recursive rollup that that uh that um proves the same game um without having to send transactions to the blockchain every time. Uh and then also uh we have Mina Foundation is running something called ZK Ignite. Uh it's cohort one right now. It's not too late to submit a proposal and get funded. Uh ZK Ignite is um a program that will help uh connect um developers or people who are sort of entrepreneurial uh designers whoever um with uh funding uh technical mentors etc in order to help them build things uh on Mina and get them off the ground.

There is 500,000 uh USDC and 500,000 MNA tokens that are available in cohort one. Uh it has a very unique um governance structure that you can learn more about in a blog post. Uh it should be at this QR code. Um and this is a great way to to get involved. You can also yeah talk with people like me about technical stuff and office hours, all sorts of interesting things.

Uh the other thing that we have is this notion page and this will have links to everything we've talked about in the tutorial. Um links to ZK Ignite, links to our Twitter's, discords, um links to uh the GitHub, um all that stuff. Uh with that, thank you so much for attending. I'm sorry it was a little bit hectic. Uh you know, oh, got one question.

Okay. Yeah, let's do a question. Hi. Somehow I missed the near zero knowledge part of the application. Who has the microphone here?

Go ahead. I somehow missed Oh, you don't have a mic. Yeah, I hear myself. Do you hear me? Uh, no, I couldn't.

But now I can. I somehow missed the zero knowledge part of the application because the the checker knows what the guesser has guessed. Yes. But the guesser doesn't know the secret word. Does that make sense?

Yes, but not through zero knowledge because he knows nothing. He has to trust the other party. No, he does not have to trust the other party. Um when they generate the hint. So if um so let's say that we were the hint generator and we tried to generate an incorrect hint.

Yes. Uh these assertions would fail. So for example, like let's say that I tried to add a uh a 100 someplace where it didn't belong or I tried to not add a 100 someplace uh where it did belong. Um because doing that would uh diverge from you know the way that this code was written at the time that we created the verification key. uh it would be impossible to generate a valid proof for that update.

Does that make sense? So the if at the end of this running this method what we get is uh basically a request to update last guess onchain. But we can only send that request if we have a valid proof and we can only get a valid proof if we've done everything like these add and if statements uh and equal statements uh correctly. So in other words, even though the um because the user runs uh this publish hint method on their machine, they don't disclose the solution that they pass in. But because we check that the solution matches a hash that we store on chain, we know that the solution that they check pass in is valid.

And then we also know that all of the work that they do in order to generate these hints um is done correctly. Does that make sense? If it doesn't, we can also uh talk more about this after. I'll stick around in like the back corner. All right.

Um so for anybody who has more questions, I think I should probably I'm about 3 minutes over. So uh I'll hop off the stage now and just say thanks to everybody. Um but yeah, the idea is check out ZK Ignite. Um tune in to the future sessions of this uh workshop. Um hopefully they'll be a little bit smoother and um come talk to me in the corner with any questions that you have.

I'd love to answer. Uh yeah, that's about it. Thank you so much for uh coming and I hope you guys have an awesome time. [Applause] [Music] It feel it yeah it [Music] feel it yeah it yeah it yeah it yeah it yeah it yeah it yeah it yeah it yeah it yeah

Automatic transcript — names and jargon may be misspelled.