Learn ZK in 90 min: A Collaborative Workshop with Mina Protocol
Ethereum Denver·Mon, 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
foreign are people ready cool all right we can start the stream then and I'll get started so this is uh we're gonna learn ZK in 90 minutes this is a collaborative workshop with the Mina protocol uh 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 it's 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 zcap 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'm Jack servia I'm a developer relations engineer at of one 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 ovonne Labs who's building Mina what's Mina Foundation Etc so uh oven Labs is a basically a zero knowledge technology company we built the proof system for 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 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 Muna ecosystem uh so this is our agenda for today first we're going to talk about snarky Jess 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 wordal smart contract using snarkyjs and then we'll talk about next steps and have questions and answers so snarky JS is a typescript library for defining zero knowledge proofs and it's also the smart contract language for the media 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 neslint and it's very easy to learn you can see here we've done a pretty good job of making sure that everything in the library has really good type doc coverage so if you want to learn snarky.js 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 code base 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 dress is easy to learn but it's also exceptionally powerful 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 create smart contracts or zero knowledge proofs anybody who writes something in snarky Jess can prove it and they don't nobody needs to rely on this you know like powers of Tau ceremony or something like that um it has custom constraints for Poseidon elliptic curves and encryption 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 the 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 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 snarky.js 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 snarky Jazz 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 guest 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 it and we get the opposite um and you can do this kind of over and over again 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 struct and this allows you to Define your own custom data types uh this is again pretty unique to snarky JS you can see up top here we have my structure which extends struct um actually let's do this bottom one my Tuple which extends trucked and so you can pick uh you know uh we can make a 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 struct 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 snarkyjs library so what's included in snarky Jazz today uh we have all sorts of types um unsigned integers 64 bits 32 bits integers are 64 bits group Boolean scale public use private key signatures and circuit string and then with structs you can you know compose these to create even more complicated data types 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 kachak 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 Merkle 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 ecosystem focused so the idea is that if you build uh user-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 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 in things like office hours Mina Foundation has programs that can help you get paid to do this kind of thing and the idea is that 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 user-facing products to have doors open to them so that they can build kinds of products that were you know just simply not possible even a few years ago um okay so how does it all work uh here's kind of an overview of snarky Jazz 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 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 snarky jazz is a typescript library this is here just to sort of indicate that it's not some kind of like wasm compiler or something it's not taking your your typescript and compiling it into something else it all is literally running in node or electron or you know a chrome window it is all literally typescript uh and so what happens is when we write things using uh snarky.js 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 Starkey JS types and these snarky.js 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 math concept it's basically 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 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 are sort of uh most fundamental uh representation of data is this field type and so anything that we make in snarky Jazz 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 JavaScript Boolean into a field element but the snarky.
js string type does know how to turn the the Starkey Jazz string into a Boolean I'm sorry into it into a field and so snarky Jazz provides classes and functions that are compatible with these field types or the structs that are composed of them uh everything that we mentioned earlier unsigned integers um booleans whatever all of these are structs that are made out using the field type and so you can make structs of structs 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 they do the simple things you would expect but instead of doing these things on JavaScript types like numbers they do it on fields or unsigned integers that are composed of fields they do it on snarky.js types and so snarky JS can represent any operation on these field types as a kimchi arithmetization which is basically a math problem that 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 snarky jest classes and functions and using the snarky.js types and as long as you've done this then snarky.js afterwards can go on an 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 when a user interacts with the snarky.js 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 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 do snarky Jazz smart contracts work well the developers write smart contracts in typescript and they deploy the verification key to a zika app account uh on Mina we have uh you know a bunch of nodes 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 so that then later on the 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 we committed to earlier our proof just won't be valid so yeah the users run these smart contracts in the browsers or a node or an electron anywhere that JavaScript runs these will run and they generate a zero knowledge proof of their interaction so uh they take this serial knowledge proof and they send it to Mina uh uh and if the mean of blockchain can verify this zero knowledge proof then we know that the transaction is valid and it goes through and if the mean of blockchain can't verify the zero knowledge proof then we know the transaction is is invalid and 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 mean of blockchain get the the circuit um or I guess like the the program the amino blockchain only has this verification key yeah so The Beano 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 it can live on ipfs it can live even on something like ethereum it really is just typescript code uh and as long as you can get a hold of it and run it uh the the amino 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 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 that then the mean of blockchain can verify using the verification key that's stored on the oh when the user sends their transaction they're basically specifying this yeah the same way the same way that you know like when you call in ethereum um uh smart contract you are 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 what 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 mean of blockchain can validate the serial knowledge proof then it commits any relevant State updates let me jump back one okay so yeah if the amino 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 your permission something like that uh and so when you run our smart contract method we get a list of things that we want to do 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 these updates to the mean of blockchain and if the mean a 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 Mino blockchain and then also some value from the state of the world this can be something like block height uh what we get out is the 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 it's just typescript code so you just import the smart contract methods that you need to call directly into your front end you know then the user does something in your front end the front end calls the the um the appropriate method in the smart contract and creates a proof and then we send this proof off to the mean of blockchain so all of the code runs in the front end and the only thing um that 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 it's a layer one blockchain that proves its entire finalized State using recursive zero knowledge proofs so other blockchains increase in size as more transactions are added a blockchain like ethereum needs to remember every single transaction that's ever happened in order to be able 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 but basically Mina does not have to remember all of the historical state 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 way to you know evaluate these transactions and then a bunch of Game Theory because we do them all in the open and remember all of them Mina uses cryptography directly to verify these transactions so it uh it uses your knowledge proofs instead of Game Theory so is this just cool or is it actually useful the answer is that it's both and for quite a few reasons uh the first is privacy so on ethereum Smart contracts run on every single node and so all 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 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 obfuscate uh data that's inherently public to such a degree that it's effectively private and this usually involves really complicated cryptography so Mina smart contracts run in the browser and this means that the arguments and the intermediary values are private by default so if we want to run Amina uh smart contract method we call the method and we pass in 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 mean of blockchain and uh Mina will verify the proof and then update the the state on chain if the proof is valid 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 zika apps run off chain 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 trend 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 mean a transaction um and in fact the mean of 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 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 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 attest to your move and my move and then I make another move and now I have a proof that's still the same size but it has 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 Mino blockchain and pass this proof as just an argument to a Smart contract method and so we can pass a proof that says hey I won let's pay out I don't know some reward to me um so yeah there's a lot of other ways that you can kind of extend this model 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 and then Mina application from you know nothing to 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 and we'll have a a follow-up session that will talk about how you can build an application specific role up for the wordal 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 mean estate using only a small zero knowledge proof and I'll kind of maybe touch quickly before we jump in any more on why this is possible um so the way that Mina works is that we have 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 and all truths and we verify them and we also verify that they have been sort of processed correctly that states and stuff have been updated correctly 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 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 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 team in the ecosystem uh they're called um uh viable systems or viable Labs I forget um but they're working on something called openmina 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 meaning 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 get it already we connect to some other nodes and then we catch up to the network 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 mobile applications that can be built into 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 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 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 else you know we'll kind of talk about whatever people are curious about so we talked about these notes 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 route of Venus so you have a Merkle tree that you know is committing to all the data and we have a root of this Merkle tree um and so the the the proof basically says that this Merkle root is correct the Merkle root 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 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 that we're at today is the correct State um because 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 and so what that means is that there's kind of like a you know there's a place we're at 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 there are a couple of gigabytes you can start one in less than an hour 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 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 that kind of thing and so these block producer nodes store everything and expose it all through 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 true I will continue to jump forward then Okay so if Mina is so easy to verify that we can do it in a browser can we do it in other places could we do it in like a spark contract for example um I'll get to you in just a second uh because I mean it's 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 mean estate over to you know their ecosystem um so yeah smart contracts on other chains can Bridge the whole mean estate just by verifying the most recent proof we have another um uh found we have another organization the ecosystem that's working on this they're called the Nail foundation and they're building in evm Mina State verification 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 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 you can see it costs nine cents on polygon um and uh the end result of this then is that the whole entire mean estate or a commitment to the entire mean estate is bridged over to this blockchain so now people who have Smart contracts running on polygon can um you know if they want to access some value from Amina smart contract they can basically you know uh pass in the Merkel proof down to this 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 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 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 values I can just call this method uh straight before 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 munismart contract will I'm sorry the smart contract on uh ethereum will also have um uh the timestamp for the I'm sorry it'll have the block height for the amino blockchain and no I'm sorry I meant to say block height well no so though the block height would have to be higher than the last uh than the the last block height that I verified okay sorry and then 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 the amino 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 amino 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 like on the users like machine locally you can do that too and you can just have your smart contract um store like a Merkle root that's committing to all this state um 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 state the block Explorer no block Explorer could analyze my transactions because I never published them you you can do this but not um there is State that's stored directly on Mina uh uh so you could do something like this you could have a state that's stored directly on Mina be used to store a Merkle root for a bunch of private state that you could store yourself and then the miracle root will not reveal any of this private information and then you can do what you want to with this private information 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 Mercury will update and to update the Merkle root on chain but the Mercury won't reveal any of the information that you're storing locally does that make sense I think it does yeah but I can not 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 your knowledge proofs with snarky jazz on Mina it's very easy to build um mechanisms that would allow you to do something like shielded me in a 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 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 jump back to this at the end for now we'll kind of keep going forward so um because snarky Jazz smart contract methods can accept and validate assigned 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 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 Starkey JS 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 snarky.
js smart contract in fact we have uh uh I guess 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 any HTTP s website or API so right now 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 middle party 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 an approvably 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 world part of the presentation we'll talk about a smart contract and build it together so if you haven't yet uh install node.js and npm uh npm install Dash G the z cap CLI uh and um and clone the GitHub repository for people who don't know uh Wordle is a game where there is a secret word and we tried 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 Bears first we can see that R is a correct letter but it's in the wrong place then we guess 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 uh we guess proof and uh and that's the the right 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 one-person game but in this case we're going to build a 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 one player 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 vote 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 and you can open up the um uh Source uh Wordle struct 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 and this is a struct uh so we're creating something called word by extending struct 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 Wordle words I'm 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 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 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 for the letters of the alphabet we pass this into field in order to create a field of this 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 if the letter is not lowercase or if it's not a letter if it's like an ampersand 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 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 uh the hash function accepts an array of fields and out we get a hash which is a single field element so we've made a struct that's going to make it easy to work with words in our smart contract it takes JavaScript words and represents them as field elements now we'll talk about the structure of our smart contract so we have um this thing smart contracts 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 these are variables that we want to store in the state of the amino 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 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 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 that you can't really like call like a a mod method on a field element it doesn't make sense there's not like a way to do modular there kind of are 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 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 do uh sorry we have this word type that we defined earlier uh using the struct and so this will represent um uh the last guest that we we 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 before users interact with the smart contract and we'll talk about that in a second uh we have a published guest 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 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 a secret word as an argument to uh to 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 snarky GS that this is a method that users are going to call the state decorator basically tells snarky Jess 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 at script 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 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 in it 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 the 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 from string a 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 and what that does is it sets the solution hash on the medal 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 we'll set it equal to a field which is equal to a JavaScript number that's zero uh so get you know basically JavaScript zero turns into field zero field zero turned in turns into unsigned integer zero and then we set this to turn number and then finally we'll set the initial guess and so we'll just make it AAA and it won't be possible to generate a hint until the guesser updates this so it doesn't really matter what this is we're just initializing it um I guess because 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 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 published 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 term number from the mean and 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 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 their 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 Gap this last guess state to our new guest so first things first we'll grab the turn number from the Mina Network a variable turn number and we'll set it equal to uh you know turn number get this get method will uh yeah contact the meter 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 network is equal to turn number in our uh local runtime and so this line is kind of interesting it uh 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 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 with 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 a 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 Caster'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 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 is our 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 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 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 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 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 guests 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 is what the hint generator does and this is a little bit more complicated but it's basically the same idea 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 meaner 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 term number at the time that we validate the proof and then we're going to add one 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 this similar chunk of code for the other method would be false um so yeah this is is doing the opposite of what our turn number check did uh for the uh published 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 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 you 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 unwinnable 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 and we assert that the solution hash is equal to the solution hash just like earlier so we checked that the value that we grabbed 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 the solution hash is equal to uh the results 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 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 hit 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 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 Starkey Jazz 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 uh 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 2 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 Gasser 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 the circuit F method and we pass in is correct position so this is true or false if it's true then we add 200 to this 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 we'll go back to it then sorry about that okay so we've got our green letterheads 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 we're 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 and so what we'll do is we'll check if the letters that 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 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 the reason being that this way we only count the correct uh number of letters in the wrong position once does that make sense otherwise you'd 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 circuit.if 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 then we can't count that letter again 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 guest 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 one five would equal five or it has values where five is 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 in the correct place okay so the final thing that we do is we take our last guess and we set it equal to um I'm 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 9 12 5 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 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 5 has not been incremented we did not count it twice um so even though there isn't 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 encode hello as eight five twelve twelve fifteen 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 212 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 uh we will have um more uh you know remote presentations in uh like uh live stream form uh that will explain how to build the front end for this how to build a recursive roll-up 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 designers whoever um with uh funding technical mentors Etc in order to help them build things on Mena and get them off the ground there is 500 000 usdc and 500 000 Mina tokens that are available in cohort one it has a very unique um governance structure that you can learn more about in a blog post 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 the other thing that we have is this notion page and this will have links to everything we've talked about in the tutorial links to ZK ignite links to our twitters discords um links to the GitHub 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 zero knowledge part of the application who has the microphone here oh go ahead I somehow missed you don't have a mic I hear myself do you hear me uh no I couldn't but now I can I somehow missed the zero knowledge 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 hints 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 where it did belong um because doing that would 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 to the if at the end of this running this method what we get is uh basically a request to update last guests on chain 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 ad and if statements uh and equal statements correctly so in other words even though the um because the user runs uh uh this publish hint method on their machine they don't disclose the solution that they pass in but because we checked that the solution matches a hash that we store on chain we know that the solution that they 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 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 three minutes over so I'll hop off the stage now and just say thanks to everybody um but yeah the idea is check out ZK ignite tune in to the Future sessions of this Workshop um hopefully they'll be a little bit smoother and 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] thank you [Music] [Music] thank you thank you foreign [Music]
Automatic transcript — names and jargon may be misspelled.