ZK HACK - Introduction to SnarkyJS and Snapps with Mina

8 Dec 2021 · 1:39:02

Izaak Meckler and Jason Borseth of Mina Protocol lead a ZK HACK workshop introducing SnarkyJS and Snapps, Mina's tools for building zero-knowledge applications. Part of a seven-week series run by ZKValidator and the Zero Knowledge podcast, the session walks through how developers can use zk-SNARKs to build privacy-preserving smart contracts on Mina's lightweight blockchain.

Speakers

Topics

Transcript

all right it's great uh well thanks for joining us today so my name is jason i'm a product manager at one labs focusing on snaps and we have isaac who is the cto of owen labs as well so we're really excited to introduce snaps and tell you more about it snaps is our smart contracting platform based off of starks zk starks and it has some unique characteristics because of that we're going to break this up into five sections first i'm going to talk about the architecture and then isaac is going to follow on uh to teach more about starkey jazz to go through a hello world example uh some exercises that build up in difficulty and then he'll wrap up at the end let's talk about architecture

mina is a layer one blockchain launched march 2021 whereas other blockchains are large and increasing in size as new blocks are mined for instance bitcoin is 378 gigabytes in size and ethereum is over 1.1 terabytes amino remains a fixed 22 kilobytes in size we call this as a succinct blockchain using recursive zk snarks the current state of the blockchain can be compressed into a single zk snark letting anyone instantly sync the blockchain and still get the security of a full node an enormous amount of research spanning decades has gone into this across multiple teams and in recent years there has been significant progress around zk starts recently our cryptography team at owen

labs has created a new zk snark we call kimchi which is setupless efficient and extensible it's based off 15-wire plug and with the amino blockchain based on zk ckstarx we're able to re-envision the design of a smart cartridge smart contracting platform so on ethereum smart contracts execute on the chain users send a transaction specifying one of the methods of the smart contracts to the chain with along with data arguments every node across the ethereum network executes these same instructions it was once groundbreaking but it's woefully inefficient mena snaps use a totally different model users execute one or more methods of the smart contracts locally and privately on

their own computer and then they generate a zero knowledge proof they send a transaction containing the serial knowledge proof and a description of associated state updates to the chain the amino network then verifies that this proof is correct for that particular snap account and if it is the state is allowed to be updated and if not the transaction is rejected clients down the line can then verify the correct state of the snap account just by quickly verifying proofs sent to the snap accounts there's no need to execute the full program like ethereum would over and over in order to confirm it so the program is only executed off-chain locally on the user's machine before it's sent to the blockchain this gives us a few advantages

we achieve blockchain scalability through succinctness because that source of truth remains a constant 22 kilobytes in size we also have the opportunity for user privacy through zero knowledge groups because these smart contracts are running locally data can remain private or public depending on the developer's choice when you write your smart contracts and then because it runs off chain you also get essentially unlimited option execution it's really only limited by the developer's choice of how much time they want their app to execute in other words it's not a gas fee based model where you have to worry about the the time and cost of it executing on chain

how does this work to define the terminology the snap consists of two parts we use the word snap to refer to both the user interface and the smart contracts within it so for instance the rest of this talk isaac is going to be referring to this smart contract within a particular step when a developer writes their smart contracts it compiles down into two main artifacts one is the priver function this runs locally in the user's web browser and generates a zero knowledge proof secondly is the verification key which is stored on chain it's sent on chain when the developer deploys their smart

smart contracts and it's used to verify the correctness of the execution and so as mentions to to deploy a new smart contract or to update it a developer has this verification key that they generated during the build process and they send a transaction to the chain to their snap to their meena address and when that meena address contains the verification key we now call that a snap account because it now functions as snap now when a user interacts as mentioned before the the user sends a transaction containing a zero knowledge group to the chain and then that verification function

which is the verifier is mean in this case it has to pass for the transaction to be valid and for the snap account state to be updated and if that proof is invalid the transaction is rejected so to dive into one last part of of kind of how this works before isaac jumps into the next section the smart contract methods can take certain inputs and certain outputs so this will be good to know when we're looking at how snarky.js works the inputs can be certain it can be method arguments so this could be data specified by the user in the local web browser when it when it runs so that's for instance your private data

you can also have on-chain smart contract states so existing states for that particular staff account and you can have also you can also have other values for this the state of the world so you could have for instance the current block height or account balances that type of thing and then additionally the smart contracts method outputs updates to the state of the smart con to the state of the smart contract and updates potentially to the state of the world all right so then isaac's going to tell you more about snarky.js which is used to write smart contracts thanks jason

um that was that was really good maybe uh maybe i'll take over the screen sharing so i can just click the slides is that cool and we're seeing some questions in here about is it based off ck roll-up or optimistic roll-ups just to clarify while i was getting that setup it's a layer one blockchain which is which is really unique to have this opportunity to use zero knowledge proofs on the layer one cool um can a friend see that okay jason can you see that okay you can see it great okay everyone hello um

i apologize i'm not a tomato um and uh i saw people saying i'm in a uh i'm a programmer in a basement i guess that's kind of true it's not a basement but you know something like that um but yeah so anyway just to pick up from from where jason left off so um star pjs is uh it's how you write snaps smart contracts um for mena and um it's it itself is a typescript library so um basically it uses existing open technologies uh that is to say you know node.js and the browser um

and because it's just a typescript library you can use existing javascript and typescript libraries and tools so you don't have to learn a whole new development environment um a whole new syntax you know a whole new set of tools um you just use kind of the existing typescript tools which are really robust because there's been thousands and thousands of person hours invested in them um and moreover uh you know a specific instance of that is we have really good vs code support um so we'll we'll be seeing that later on um in in the presentation so um yeah so like the intended uh development

environment for snarky gis is using vs code i mean you can use whatever typescript or javascript environment you want but i can i can report that the vs code support is very good um so just to kind of start things off um the basic unit of data in zero knowledge programming is a field element and i'm sure you've uh heard about this a lot throughout all the presentations so um hopefully this is familiar to you but basically a field element is is like a number um a very big number so a number which is almost 256 bits in size actually um our specific field uh it's a little bit uh less than 255 bits but

um you know you can think of it as being something quite similar to uh 256 and solidity um so uh what can you do with field elements basically um the basic operations you can perform with them are like addition multiplication division subtraction that kind of thing but we can build all sorts of things uh out of them and in fact the standard library for snarky.js has already done done so um so in starkey js this is represented by a typescript type called field um and uh yeah so uh in typical you know typescript or javascript programming you could write

you know this like sum the sum of two numbers is you know one plus three um in starkey js because field is kind of its own type you need to you know kind of wrap it so um the way that you write like a new you know create field elements is you write new field um uh you know some input which would be a number or a string representing you know the valid field element and then you can do use dot add on that um and actually so here you know we we have like new field one dot add new field three um for convenience this can actually just be simplified to just say like dot add the number three um then snarky.js can you know figure out how to wrap that

um [Music] cool so i'm i'm gonna be looking at the questions every now and then but um looks like we're all good so uh there's a lot of other built-in types besides field elements um so as i said there's fields there's also un-64 un 32 public key private key and signature so there's a built-in um signature scheme libra into the center library um because that's a really common kind of functionality that people would want you know want to use in smart contracts um there's also types for sort of representing optional data booleans um a group type for sort of you know representing an elliptic curve which is

useful for a lot of cryptographic schemes um and these all have built-in methods on them that we'll see uh in a little bit so to sum up there's a whole bunch of useful functionality um providing the standard library and uh it's has an all has a nice typescript interface and we'll we'll see that a little bit so uh just a bit of a primer on some of the basics of snarky.js so as i said it's a typescript library and programming is very much as it is in typescript or javascript so just to give a really simple example here's a function that takes in an input field element x and outputs a field element so this is

how you write this um and it works by you know the function is called add one and double so what's it going to do it's going to take an x it's going to add 1 to it and it's going to multiply it by time multiply it by 2. and that's exactly right x dot add1 dot multi and you know just to kind of show you a little bit of syntax if you want to create an intermediate variable um you just do it like you do in javascript or typescript you can use let um or const uh if people are familiar with javascript um and you know you can define this intermediate value x plus one just do x dot one and then you just return you know x plus one double two so

so okay so uh just to kind of sum this up like the basic syntax of it is just typescript it's just javascript it's just typescript so if you're familiar with that um this circuit js will be very familiar to you um from here we're going to basically uh look at a hello world snap example to kind of get our feet wet with um uh how programming smart contracts and stock.js looks so um to get set up there's three things that uh that we need to do and i know that this takes basically five minutes because i just did it right before this workshop because i'm on a mac which i usually don't use so the first thing you want to do is

install vs code if you have vs code installed already great otherwise there's a link in the slides the slides should be in the chat um and then the second thing you want to do is uh install node.js with npm version 16 or later you can you can use the link here and then the third thing is you're going to clone the gear repo specific to the workshop so um i can drop these links in the chat for people to install and i'm just going to wait like a couple

minutes here um for anyone who you know wants wants to do that um so just putting in the chat now and i'm going to put the get link to is node 14 not supported um i'm not sure uh i'm sorry it means it is supported but you have to run it with a specific flag let me look it up okay uh maybe actually gregor can post it because

i don't have a problem you can use 17 too i um so i i'm i just tried it with 17. so i know 16 earlier works i think um yeah as jason said if you run it with an earlier version you have to use a specific flag [Music] um oh i won't yeah okay looks good ugh

anyone else getting an error that repo does not exist hmm oh did i forget to oh sorry i uh my bad i'm gonna i'm gonna i forgot to put https on the thing i guess oh no no no it's that uh actually that they delete the http yeah okay that's annoying so so uh yeah so basically i oh wow someone figured out how to do it right click paste okay so yeah thank you to to jeff arnold for and and you and younansha for putting the right way to

clone the get repo just a quick question isaac and actually jason are you seeing the screen because for me right now it's gray and i just want to make sure that there's still something up yeah i can see the screen you're seeing it okay all right oh yeah it's back for me how's everyone doing well i i guess

people can't reply but i hope everyone's doing well um it's a nice morning over here you know having some coffee oh yeah people can reply in the chat that's good oh there's some questions in the q a tab okay um okay so i'm gonna while we're waiting for people to get installed i'm gonna wait a few more minutes i'm just gonna read some of the questions in the q a tab so anonymous asks well no no i'll go in reverse order harass g asks since the computation is off chain is it

fair to say user could be censored to use the snap so haresh that depends on how the snap is set up so uh in the typical setup no the user cannot be centered because uh there will be a permissionless you know way for the user to run the application um and and they will just execute it on their own hardware um like on their laptop or on their phone or whatever um and then posted proof uh to mena and you know mina is like a normal blockchain like censorship resistance so that execution proof is going to get incorporated into mina um as you know just just as like a normal like kind of smart contract

transaction would get incorporated into um like ethereum so anonymous asks why would you want to add and multiply field elements instead of uns uh that's a good question so um let me put it like this uh well first of all there are certain settings where you just want field elements so like for example if you're doing operations with an elliptic curve or um with some kind of scheme cryptographic scheme very often uh you need to you need to use field elements because you need to be able to divide basically so in a field you can divide um in a nice way in uh in with you ant 256 or whatever you

can't really divide exactly you can sort of divide but it's not real it's not really division and so you can't do all the things that you sometimes need to do in a field so and then this the second thing is uh field elements are kind of the native value in um in most proof systems and in particular in our kimchi proof system so um what i mean by that is you know like on a cpu intel cpu let's say uh the native value is maybe well i don't know it's maybe a little bit hard to say but like natively it supports operations for like doing 64-bit integer arithmetic for example

uh that's the same in our proof system the native kind of operation it's supported is field arithmetic so um that's kind of the native value uh okay so just moving along mursad uh uh ayanovich asks do we have to put along um you don't have to it's up to you um oh man so many questions uh kobe asks is a snapdev company going to be running their own proofs or will they part of be part of the snark marketplace or some kind of distributed worker pool so uh again it kind of depends on the setup of the application um you could deploy a snap that has you know that is

sort of uh running as maybe kind of like a roll-up situation in which case you know you might have one operator you might have an operator or you could have snaps that um you know the approver uh the user kind of executes the proof individually and then kind of broadcasts its broadcasted to the amino network and it'll be part of the stock market place there um marcos asks is the work workshop code yarn compatible i don't know um maybe gregor or uh brandon if you know or martin in the chat can answer um what's the equivalent of etherscan.io for mina um forgive the perhaps dumb question is code visible for a smart contract how does this privacy visibility tradeoff work

that's a very good question um so uh there are meena block explorers um if you for example if you go to mediaexplorer.com you can find a very good block explorer um it's not a dumb question at all is code visible for smart contract is an excellent question um by default it's not so uh what happens is basically the when you deploy a snap account you put kind of like a commitment or a hash of the code on chain and then uh later people come along and post proofs that kind of verify against that commitment or hash of the code so by default the code is actually not available on chain um but you know in most applications or

in a lot of applications you would want to share the code so that people could interact with the smart contract um okay uh bo yao asks what kind of offline compute calculation can you use you can you can do anything um it won't necessarily be verified but you can do anything you can do in javascript um francesco asks are snaps composable yes they are we if we have time we'll get into that a little bit um florian asks we touch on token as well i've seen references to token id and token symbol and code i won't uh be discussing that in this workshop unfortunately but i can try and say something about at the end um and jeff asks do a few examples

in context of decentralized dk roll-ups i'm interested in centralized proverbs especially it seems circuit js may allow for the development of uh peer-to-peer z cares um at the end of this workshop i'm going to show a little example that has to do with roll-ups and you know maybe you can uh draw you know you could build the browser-based peer-to-peer zk roll up using it actually so but we'll we'll we'll get to that in time okay um i'm gonna uh assume that people are are installed now it's been a while um [Music] and uh you know uh keep going so all right hopefully everyone is in a in

a good place it's been about almost 10 minutes so you know hopefully that's good and let's move on right so uh hopefully you cloned the workshop please cd into the workshop and run workshop repo directory and run npm install hopefully that works and we're gonna now go through hello world together so um we're gonna write a very simple smart contract with a single state variable named x okay it will have a method called update that will let us replace x with its square so like

for example if x starts out being three um if we call update we can provide update you know with the square of x9 and the smart contract will say yup that looks good that's the square of the current state and replace the current state value with nine then we can do you know once it's nine we can do object 81 81 being nine squared and that will set the new state to e1 and just to kind of drive the point home um let's say you know we perform our first update x is nine and then we try and call update with something which is not nine squared like 75 then basically uh the execution will abort

um and it'll say hey very bad you did the wrong thing um and it will not let us update the state to 81 or to 75 rather so um to write a snap what you do concretely is you create a class which extends the smart contract class of snarky.js so um it's simple as that uh and the way that you declare well okay so like a snap can contain some on-chain state um and uh the way that you declare this on enchant state is basically by writing properties for your class

and annotating them with the type of the field the type of the property that is that is and with the state decorator so here we're declaring a state variable on chain state variable x um this says it's a state variable type field and this also says it's a state variable of type field um it's it's i apologize for the slight verbosity um uh only by default only types built out of field can be used for state variables and i'll get into a little bit of what that means in a bit um so this is a lot like how it works in solidity this is a very similar concept

and solidity you know you declare when you when you write your smart contract you kind of declare a class like this you decline you you define properties on this that class in much the same way um so it's very similar so uh the next ingredient in defining a snap is to define the constructor so this describes how the snap will be initialized when it's deployed um there's two kind of parameters that you pretty much are always going to have when you define a snap which is the initial balance of the snap account and the public key that owns the snap account so uh this is what a constructor looks like um oh yeah so in addition this

constructor is going to take the initial value for the uh account state x and um it's simple as you know so you call super address so that's just something you always do um you basically add to the initial balance you add to the balance of the account the initial balance that's provided and uh you initialize the x uh state state variable with um this value x that's provided um now uh once we've deployed a smart contract we want to start giving it behavior so any smart contract can can contain

multiple methods that each have their own logic so the way that we define that is by defining methods on the class so for each method you you basically write at method then okay so this method happens to be async and i'll get into that in a minute um it's called update and it takes one parameter which is a field element um so what's this method going to do basically first it's going to get get the on chain state of the x state variable then it's going to square it and assert that that is equal to the provided argument um and then it's going to set the

on-chain state variable to that squared value so in essence what this is doing is exactly what we described on a few slides ago which is it's it is a method on the smart contract that can be called uh only with the square of the current state variable so as long as you provide the square of the current state variable um this assertion here x dot squared dot assert equals squared is going to pass and then it will allow us to get through to this line the final line which sets the uh sets the on-chain state to that squared value and the methods of a smart contract just like in ethereum basically describe

how it can be invoked when you deploy when you deploy it so just a note on you know what's public what's private the state of a snap that is what's defined with these state variables is public um it's on chain and it's public unless it's explicitly stored as a commitment to the state so um you know for example a very common pattern would be to store on chain the uh root of a merkle tree and then um you know that's like a commitment to the state it's hidden the state is hidden in that case and and uh store the merkle tree off chain

somewhere uh private um either like on a user's own device or in some kind of you know private cloud setting um and then uh interact interact provably interact with that state by using um like the miracle tree functionality this in starkey js um and that so that would like keep the entrance state hidden but um uh still have the the chain be kind of publicly available in a sense um now what's private uh any argument to a method oops sorry any argument of a method is private um this comes from the zero knowledge that's that's used um here unless for example um a method like

takes that argument and then stores it into state then it would become public but um we'll see examples later on of where it's very clear kind of like how uh the method you know how the arguments of methods are are private um so uh just a note on this async here next to the definition of update um the update method is async because it calls dot get so uh it goes to the chain and grabs the value from the chain um and so that's why it has to be async because you know we're actually running this off chain so this like fetch of like going to the chain and and grabbing

the value from it is going to be async and we can use this really nice async await syntax and javascript to make that nice um so i'm just going to pause for a second now and just look in the comments uh if there's anything here um okay seems like a lot is uh being covered

yeah all right if you do want to take any questions just remember to read the questions so that um we can also hear the question and the answer for the video after okay that that makes sense um [Music] cool so uh there was a good question here well they're mostly being answered oh okay so someone asked oh this is a very interesting question why is the dot set method not async or is it but you forgot to call await actually it's not async and the reason for that we will understand in the next slide um so i'm gonna go to the next slide and

then we can try and understand that a little bit so let's think deeply about what happens when we call uh on this snap in terms of what is the actual zero knowledge proof that we do what is it that we actually prove here's what we prove quote we ran the code in the update method with some arguments and the resulting effect was up to perform the following updates set x to be nine assuming the precondition x equals three so uh basically when we run this this snap locally we get out a proof that says

i am allowed to update the state of the account for this contract to nine assuming uh that x is currently equal to three so um i think jason covered this a little bit when we actually run a snap what we're doing is we're generating like updates to the on-chain state given some preconditions um and then those preconditions will be checked on chain before the snap transaction is actually applied so this answers the question of why is set not async because actually uh it's more like proposed setting

so um you know we're kind of in a fantasy world on our own local computer we can do whatever we want we can say yes set this to that set this to that set this that and it's all okay as far as we you know by us and then we're going to send that to the chain and the chain is going to say you know then actually perform the setting so um and we'll see how we actually can wait on that execution but um yeah like in the context of a single snap we're we can just go set willy-nilly because we're just kind of operating on our local view um okay so uh all right so okay so philip asked what happened with multiple people run update

nine currently that's a good question the updates will be will only one of them will happen you know most likely unless they don't require unless their preconditions are not conflicting so but in this case um you know only only one of them will be performed um all right so i'm gonna i'm gonna keep keep on going here um so just to summarize uh the anatomy of a smart contract um we have state variables which are public we have the constructor which describes how the how the contract can be deployed and

we have methods in which arguments are private by default that is to say they're private except for what's sort of explicitly exposed about them um and what the methods do is they produce sort of these preconditioned updates okay um so now we're gonna recall that we downloaded uh the git repo and npm and stuff and we're gonna run hello world um and this is as simple as running the following command we wanted to kind of show you what's going on under the hood all that we're doing is running the typescript compiler and then running node on the resulting file so i'm going to paste this command into the chat

give me a second okay so everyone yeah great okay alexei uh was able to run it so um oh yarn running sec okay i guess you can do that too great it runs okay so let's let's let's take a look at um what we are actually doing with that run and now i'm going to share my editor i guess i'll isaac did i'll reiterate um so why is set not awaited um and the reason is that because the smart contract executes

locally in the web browser we wouldn't want to set the states while that smart contract is being updated because let's say the user never says the transaction to the chain or the transaction is rejected by the chain you don't want to have updated it during the contract execution so instead when the smart contract executes it outputs both a proof and a list of associated state updates inside a little more detail these state updates are also passed as one of the inputs while the proof is generated so when both these pieces are sent to the chain we know by having passed them in we know that those state updates are are valid and accurate for that proof in

that transaction and then if that proof passes on chain we know that the transaction is is appropriate and has run the proper expected code as well and then we can update the state at that time so it's the the state update is occurring when the transaction arrives at the chain and not during the execution in the browser so that's why it's not weighted in the browser hey again our slots composable uh yes so um we have not uh implemented this yet but um well fully

the back end is but you can a snap can call another snap and and pass it in between the two yes they are uh possible oh what a pain is this the eight field array publicly visible on a blockchain yes it is so what the question is about is we have eight fields of 32 bytes of on-chain storage right now it's arbitrary in the sense that the snap developer can choose what data they want to store there and one thing that we're exploring for the future additionally is uh using off chain states so what you could potentially do is store the root of a merkle tree

in that one chain storage and then store the actual data itself and uh some kind of other decentralized storage off chain uh so yeah i think that answers that let's see what else are you jason's quick question are you seeing the questions coming in on qa as latest because there's like a bunch of new ones kind of popping up at the top [Music] [Music]

yes oh let's also explain uh a little more about i saw a good question earlier about where does the smart contracts execute where does the contract code live so we mentioned it it executes in the web browser and then a snap it equates in our terminology equates to the user interface uh plus a smart contract so as an analogy let's say that you go to the uh uniswap website there's a user interface for people to interact with it but in our case there is the actual smart contract code that lives there as well so the developer sends that smart contract javascript and wism code with their website and if you're concerned about security

with this just remember that we're generating as your knowledge proof so that zero knowledge proof will only be accepted by the chain if it matches to the perimeter function to the code that that developer had deployed so you don't have to worry about security risks in that at all um but so where does the code live the smart contract code itself um it just lives as part of the developer's website the javascript okay it says if a value is sent to the chain how long is it stored there so um let's let's say when when state is updated on a snap account how long does it remain there uh because that's how volumes would be stored right

permanently so it will remain in the the on-chain storage will remain there permanently um and also how the mean of blockchain works we have the recursive zero snark which represents i like to call it the source of truth um it's what allows people to interact with the node without having to download the entire history but that history is still available um through other node operators we call them archive node operators and they have the opportunity to to to store it in any different location it's really their choice and but that has the the full history so in this

case we will have something called events which update the state on a snap account um and you could for instance see the entire event history uh associated with that snap account uh which would live on the archive but not on but it wouldn't be needed for uh knowing the again like this the source of truth knowing that for achieving that full full node consensus uh you don't need the entire history that's that's the advantage of the recursive jurisdiction so yeah all right i'm gonna i'm gonna hop back in and so jason you and i need to bounce off so that we have the full screen for folks to see that

um yeah it's a bit sometimes it's a bit tricky to look at codes also just maybe pay attention you can close the chat if you want your screen to be a little bit bigger you can also make it full screen okay i'm gonna jump off too cool um yeah just let me know if uh it's hard to see so um right so okay everyone ran in hello world um that's really great it looks like everyone got their expected output and i just wanted to kind of run through with everyone what it looks like to actually call the smart contract so um first the first thing that we do is uh we set the kind of active instance of mina that we're using could be this local

mock blockchain just for testing and you can see like the vs code support's really nice so we can hover over local blockchain and we get uh we get this doc comment okay so local blockchain a mock mean a blockchain running locally and useful for testing great that's what we're doing um then we're gonna set the active instance just this local one um we grab a few test accounts that are just you know we're going to be using them for descending transactions create a key pair for our snap and then we are going to create a instance of our hello world snap app and the way that we do that is by creating calling meena.transactions so meena.transaction is how we actually like create a snap transaction and

within the function that we provide to mean about transaction is where we actually run our computation so what we're going to do inside of this first transaction is just deploy the snap so how that's going to work is we're going to basically create a transaction that involves that's sent involving account 2. account 2 is going to send this amount and the way that it sends it is just by decrementing its own balance by that amount and then we're going to call uh new up with our snap class with the the given amount the public key that we defined and the initial state for the snap which we defined to be three so that is how we initialize the snap

instance and then we called you know that's going to give us a transaction we'll call that send on and then we wait for that transaction to be sent um next thing we're going to do is create a new transaction for updating the snap um again we call media.transaction within that we can call our snap method update um and provide the square so we do snap instance.update with the squared value and then we're going to do a failed update which a lot of you already noticed so we're going to try and call update with the wrong value 109 and as people pointed out this is going to fail because 109 is not 9 squared and yeah so that's kind of how the hell

world looks and now with that i'm going to return to the slides so one second i guess i'll turn my video back on on a different computer now cool um can we see that yep so uh back to the exercises so um now that we have seen hello world and we have kind of a feel for how snap

accounts look and snap transactions look we're gonna do a few exercises together um and i just want to call out um how to kind of get a sense of the api so there's two good ways of doing that one is we have an api reference um api reference docs available here at this url and you can you know go through the slides to grab this url but the other way that's really good is just by using autocomplete so um as i mentioned uh we have really good vs code integration because it's just typescript and on anything you know any any value you can just type you know period and to see all the methods and

uh vs code also shows comments so there's inline documentation as well um all right so let's do our first exercise together um this will be a little bit of a warm-up um as we kind of went over already we're going to be using a mock media environment that just runs locally and our first exercise is going to be the following so open the file one underscore exercise dot ts it's in source and what we're going to do here is input is implement update so that uh instead of setting x to its square we're going to

set x to its cube okay so for example 3 should be able to be updated to 27 and then 27 should be up to be able to be updated 27 cubed which is 19683 so that's going to be the first exercise and yeah please please try that um in your own looks like we got our first uh finish from chicago um

your unsure is asking how to finish um so right yeah just do the to-do in the file so if you open sorry if you open one underscore exercise.ts you'll see online 25 i believe that there is an error and the goal is to basically update update this method so that similar to exercise one where we set the value to x squared instead set it to x cubed oh you don't finish it five minutes ago okay nice you get the bragging rights yeah so zooher says their cube doesn't

exist that's right there is no cube method you need to uh implement it in terms of the methods that are available like yeah.mall for example you could use or dot square hey no spoilers francesca um okay so uh looks like some people um had success uh gonna uh going to move on here um our next exercise is going to just explore hashing in smart js just to get a little experience with the api so

you can open the file to exercise dot yes and um what what you're going to do there is use use the function poseidon.hash which is provided by snarky.js so that x is set to instead of being set to its cube it's going to be set to its image under the poseidon hash function okay um so that is a pretty similar exercise you should be able to just see that um i'm just going to answer just a question from this uh from anonymous are there benchmarks available

and how long it takes to produce a proof running it on my pc seems to take about four seconds how does execution time grow linear okay so two things um basically all of that four seconds actually comes from loading uh wasn't so in a in a real application that would be kind of like just an initialization time and we're we're working on on cutting that down because it really shouldn't take that long so sake js runs using rust code that's been compiled to awesome and and basically all of that four seconds is um uh coming coming from from awesome but yeah in general execution time is

you know roughly linear in the complexity of the computation all right so this will have to be resolved after the workshop it does seem there's some bug um in the example code um because it's not setting the value to the correct uh poseidon value it's actually just setting it it's not sending it at all it's actually feeling adopted it i think so um we'll return to that later but it's annoying um all right oh so luca asks can we see the solution anywhere yes two things if you ever want to see the

solution there is a branch called solve and so you can just check out the solved branch [Music] and let me just run through the solution really quickly so this one was slightly different from [Music] the other exercises so uh in this exercise um you have to call the side of the hash function and notice that it takes an array of field elements so you just pass it in an array of field elements and set x to that value but as i mentioned something funny

is going on because um the correct value should be this which is just the hash of three with poseidon but for some reason it's not updating so um i guess a last minute update just to the this workshop code uh introduced some bug somewhere so i apologize um it it was working the other day um when i ran last so um we'll we'll go back and you know make sure nothing funny is going on there um cool so let's move on to the next exercise um so the third thing we're not going to do as an exercise because

there's too many concepts introduced so i'm just going to explain it how it works um and that is payments so um you know on mena there is a cryptocurrency called mina and very often what you want to do is move you know money around basically so this can be done as market js um i'm going to walk through with you you you all how to do this so what you're going to want to do is open three exercise.ts and i'm going to open it here and then we're going to go through it together the branch should be called solved i believe unless it's not pushed all right everyone

uh cool so three exercises let's go through it together so this the way that this is gonna work is it's gonna be the same as exercise two where we update the state by replacing it with with the poseidon hash but uh what we're going to do in this case is anyone who updates the state we're going to give a reward we're going to give them some mina for performing the very useful task of doing a poseidon hash and uh the reward that we're going to give them is going to be one three three seven minutes um so our constructor here is of just a vanilla constructor the same as we've seen so far so i'll just kind of close

that and now let's look at the update method so you'll notice this is the same as it was in the solution to exercise two we just set the state to the poseidon hash but in addition we call this.balance.sub in place uh reward so what what that means is when you call update you're also going to subtract from this the snap account's balance the value 1337 okay and you can see there's this dot balance dot add in place and there's this stuff balance that sub in place so what that means is when you call this this this uh method the

accounts balance is going to be decremented by 1337 and what that's going to do is basically make available 1337 for any other party in that transaction to add to their balance so if you look at how this is actually used in the transaction that where we call update we're able to create another account corresponding to account 2 and then we can do winner.balance.add in place the same reward and the reason this works is when we run this transaction it checks that all of the changes to the balances sum up to zero so what that means is nomena is created or destroyed um

and uh and and so it's a valid transaction so that's how payments work right now in snarky.js is um by modifying the account's balances and we can go ahead and update this cool and you can see um once we've updated it the winner the winner balance has had one three three seven added to it um to have this grand total so that's a bit on how to do payments in snarky.js

by modifying account balances okay cool someone asked how do you burn mina is there a burn address florian replies uh you can use my address as a burner dress so if anyone wants to burn mina just send it to florian um cool all right moving on great so uh just to kind of review the payments you basically use the balance dot add in place and got balance that's up in place and that's how you can move me around between accounts and then as i mentioned all balance changes in a transaction have to sum to

zero okay so exercise four is just going to explore how you can use functions and loops um in snarky.js so as i've mentioned in snarky.js we can just define normal typescript functions and we can also use normal for loops so um what that looks like is just a javascript or typescript for loop um you know here's a for loop for example um and it's you can you can use it just as well on snarky.js so um for this exercise open the file for exercise.ts and in that file there's a function called hash n times and the idea of this function is is it should provide it

should um apply the poseidon hash function n times uh so you give it a number n and an input and it should hash that input n times um and uh you should use a for loop to well or whatever you want maybe you could also use recursion i guess to implement that function we use normal for loops so what that looks like is just a javascript or typescript for loop um you know here's a for loop for example and it's you can you can use it just as well on snarky.js so for this exercise open the file for exercise.ts and in that file there's a function

called hash and times and the idea of this function is is it should provide it should apply the poseidon hash function n times uh so you give it a number n and an input and it should hash that input n times um and uh you should use a for loop to well or whatever you want maybe you can also use recursion i guess to implement that function double b said i can run three without a

balance actually yes so in the mock mena environment it doesn't enforce uh that that the sum is exactly zero i believe that it enforces that it said that it's greater uh or that no meena's created but it's possible you actually can burn mina in the mock environment on chain you cannot earn mena so that's a i guess a discrepancy that should be resolved someone asked can you send meena from

within a smart contract function can you verify the address that mina is sent to somehow um can phillip can you can you elaborate on that question i'm not sure i understand we have a bunch of people who were able to do this so that's awesome i'm gonna wait a few more minutes and then we can go through the

solution together um okay so uh let's see philip was i'm just gonna go back to philip's question to me it seems like exercise three only subtracts smart contract balance so that in the same transaction anyone can claim that subtracted balance but is there a way for the smart contract to limit the balances that the reward can be sent to yes um you can you can you know enforce that um the receiver is equal to some specific public key that you know you compute or depends on some other part of the computation you can you can do that um great so a lot of people got this um

answer and i'm just going to share my screen to show everyone how it looks so right we wanted to implement this function hatch m times um it's as simple as the following so i'll i'll actually just rewrite it so first we're gonna just say okay the result initializes this variable res result to x and then we write a simple for loop so let i equal zero oops i is less than m plus plus i and then we're going to say res is equal to sine n dot hash and then we need to provide an input and we're going to provide res so we hash ourself

um n times and then we just return that and then um when we run it we get as uh well first there was to do but then we get as people have been posting in the chat um this value ending in 864. so that's the result of hatching the initial state value into itself uh 10 times cool oh yeah you know sure has their recurs recursive example i guess we could do that too that's pretty cool um oh if n is equal to zero return x oops x otherwise

um uh exciting dot hash of hash n times minus one x no uh i guess that's right i mean that's not cal recursive or whatever but um does that work let's see i don't know it's kind of fun to do recursion i guess yeah cool works just as well if you want to be fancy um cool all right so let's

move on to our next exercise um alright so in this exercise we're going to learn a little bit about how to kind of implement logic um so uh one of the most important things for implementing you know logic i guess business logic is this bull class so bool uh differs from the type boolean so in typescript there's a type called boolean which is the normal boolean type true and false bool is a little bit different it's booleans that can be used inside of zk snarks so um they're very similar to normal booleans we have the kind of typical boolean methods um you can call

dot and you can call dot or you can do dot not to negate it um but you cannot use bool in an if statement so boolean you can use in an if statement bool for button not allowed to use an if statement instead you have to use this kind of ternary construct which we call circuit.if and what that does is it takes it takes either a bool or a boolean and two values like a then and an else and it returns a value so if the bool is true then it will return the first branch if it's false it will

return the second branch and this is something which you may have seen in other presentations which many proof systems including kimchi currently although that very very well might change in the future does not really support branching in terms of execution it supports sort of branching in terms of values so if you want to do branching you kind of have to run both branches to get a value and then use a kind of a ternary expression um although that may change in the future that's currently how it works um so that's just kind of a little bit of an overview of how logic works we're not going to use if in this exercise but i suppose you could actually

but just for people's reference so okay so this exercise is going to be something a little bit more interesting than just updating state and we're also going to see a little bit of how zero knowledge comes into play what we're going to do is define a snap account that you can send from if you provide a signature from any signature from any public key in a given list okay um you can think about this as kind of one out of n multisig so this is how you would implement one out of n multisig in muno um now i'm going to switch to the code view all right

five exercise all right so um the first thing we're going to do is define a type so uh in snarky.js i i said that any value that you want to use as an argument to a method has to have um has to somehow be built out of field elements and concretely what that means in snarky.js is you extend this circuit value class so if you want to have your own type that you can use um as an argument to method you extend the circuit value class and so this is just going to be a simple type that's going to represent a signature along with the signer of

that signature so it's just going to be a class that has two pieces of data signature and signer a signature and a public key now let's look at the smart contract itself it's going to have a parameter which is the list of owners of the account so we're going to do one out of n multisig against some list of owners and that's simply going to be an array of public keys now notice this is not a state variable but a contract parameter so what that means is this list of owners is not stored on chain it's actually kind of hard coded in the code of this smart contract and as i mentioned in response to a

comment the code of a smart contract by default is not publicly available it's not stored on chain only a a hash of it kind of is stored on chain um so okay so how uh are we going to implement the one out of end multisig um we're going to define a method called spend for our smart smart contract and that's going to take us two two arguments one an amount and two a signature with a signer then um what we're going to do is check that the signer in that signature is equal to some public key in the list so we're going to use some func we're going to define a function called contains

publicly it'll take a list of public keys and a public key and return a bool so it will return true if the given public key is in the list and false if the given public key is not in the list and then we're going to assert that that equals true so this is going to check that the person who created the signature is in our list of owners next we're going to verify the signature against the given public key and i also added a nonce state variable oh no sorry this is the nonce from the account so all accounts have a nonce and we're gonna verify the signature

against and on so that signatures can't be reused um this isn't really necessary but just to kind of give you an idea of how to use the knots as well uh finally once all if we get through here we can uh spend the amount and now we just do again by calling this.balance.sub in place okay so that's the logic of how this multisig works [Music] and just to explain a little bit well actually let me go back to sharing just to explain a little bit how zero knowledge comes into play into play here as i said all the meth all the arguments to a method are by default private and so what that means is

this signature and the public key along with it is totally private so when you execute the smart contract there's no way if you look on chain there's no way of knowing which public key in the list was it that uh authorized the spend that is totally hidden by zero knowledge and moreover if the account code is is not published anywhere so like if you just create this and share with your friends who um have some of the public private keys corresponding to the public keys and the account um the list of public keys is also not private so um all the logic of how this works is also can also be totally hidden all right so

for this exercise what you're going to want to do is implement this contains public key function and what i recommend is check out the methods on public key and in particular check out this equals method so this takes another public key and returns a boolean checking if they're equal so see if you can see if you can use the equals method um to check that this public key x is equal to some element of this array i'll just give you five minutes to do that yeah yeah uh so let's let's take a look

here um [Music] hey jason um asks a good question and jason gave a good answer uh abel b's question was so the availability of such list of public keys is on behalf of the client and could be lost forever indeed to quote jason uh in isaac's example that's me uh he chose that's me i chose to maintain the privacy of the list of public keys alternatively you could store it on chain if desired but it wouldn't be private in that case of course true also you could store it somewhere else off chain so you could store it

on ipfs or you could store it on a server that you have somewhere or you could store it um on a hard drive uh in your basement i don't know or whatever there's also a good one that's i've seen a couple types in here what happens if you have an infinite loop very good question so um if you have an infinite loop okay uh the let's see how can i explain this um sorry go ahead jason you're gonna say

let's have it so uh because it's just javascript and it's running in the user's web browser an infinite loop would result in a smart contract that doesn't finish execution and if it doesn't finish execution you're not going to generate the zero knowledge proof or the transaction so you end up in a state where if you have a broken smart smart contract the developer would need to fix their code and redeploy in order to have successful user interactions again yeah and actually you wouldn't you probably depending on what your loop looked like you probably wouldn't even be able to deploy it because um [Music] we kind of run the whole contract to generate a circuit um and if you have an infinite loop like that process is never gonna finish so

all right so uh i hope everyone had a chance to check out that exercise i'm going to [Music] share my screen and oh you just muted yourself isaac we just didn't hear the last minute or the last just the last thing you said not minute the last like oh okay i'm right so i'm just i'm sharing my screen to show the solution all right so uh contains public key well here was my implementation it's kind of functional programming style we map over the array of public keys and for each one we check is it equal to x

our input and then we call dot reduce with bull.org so it's going to say like either it's equal to the first thing in the list or it's equal to second thing or it's equal to third thing or blah blah blah if we were so inclined we could also use a for loop so we could say oh let res new rule false and then say you know i equals zero i is less than x's dot length oh this is the generic version okay anyway uh oh sorry i'll go up here so we can do the specific version um i is less than x is that length plus plus i um result equals resolve dot or

um x is i dot equals x and then return result so that would be another way of implementing the same logic and i'll just mention typescript's type system is very powerful and this can enable us to you know program in a really nice way for example we can write a generic version of the contains public key function which would check that anything is contained in a list as long as it implements this eek interface that i defined right here so this function can take a list of anything an array of

anything which implements the eek interface and return to boolean and it works in exactly the same way the code is identical i can even replace it with this imperative version people like that and in all pipe checks it works great so that the really nice thing about using typescript is you have this great type system that's very flexible um and uh and yeah and very powerful um all right so uh cool i'm back so

um a bit of review with this exercise um we use here a user defined type the signature with designer and i just want to point out how this works if you want to use a type as a method argument i'm just i know i said this already but i'm just saying i'm going to say it again if you want to use the type as a method argument or a state variable you must number one extend this circuit value class and number two use the at prop uh a decorator on all the properties in your class and that's going to enable you to use it as a method argument or state variable so uh with that we come towards the end of our

uh exercises and uh can i get a time check there's 10 is there 10 minutes left is that right or do i have more 40 minutes i'm not sure yeah you have more um you have what is it it's like it's 10 20. 25 minutes yeah beautiful i mean there's lots of other there's lots of questions we can talk about so i don't think we need to so i'm gonna i'm gonna go to the end of the presentation and then i will um and and then we'll we'll do questions perfect all right so uh we're very close here thank you everyone you've been a beautiful audience uh in the chat very patient and um as a little as a little treat we're

going to talk about um how recursion looks like in snarky jazz so recursion is oh recursion is a very uh i feel like currently kind of an arcane thing so what i mean by that is it's very it seems kind of complicated and like specialized and you know blah blah so what is recursion it's verifying zero knowledge proofs inside of a zero knowledge proof and this is a really powerful technique because it lets you do a lot of things for example um uh like implementing um roll ups zk roll ups is is really easily done using recursion and a lot of the teams that are implementing zika

roll-ups do it using recursion but it's really complicated and you know kind of hard to get your mind around and really hard to implement because it requires all this crazy cryptography um and in snarky.js uh we this is not uh yet fully public um publicly available but we have an interface for making recursion a snap which is an idiom meaning making it very easy um and we can it's so easy that you can define a simple zk row up in like only 150 lines of code so let me show you what that looks like um if you open

if you open in the repo this bonus file you can get a feel for it so i'm going to turn up my camera open bonus i'm not going to go through this whole example because it's pretty complicated but as you can see the core of this roll up is from line 87 down to line 148 so actually only 60 60 lines basically um 61 lines and it makes uh defining uh this under the hood this uses recursion

but um it can be defined really simply and easily so this rollup is going to be like defined as a proof system and it's going to have sort of three three branches to that proof system one for processing deposits into the roll-up one for transacting on the roll-up and one and this is where the recursion comes in for combining two proofs together to get a single proof so this is kind of the magic secret sauce of recursion is that you can combine proofs together to this this takes two different roll-up proofs and returns a roll-up proof and this is actually a lot home like how mena works so

um the logic for uh merging two two things and don't worry if this is confusing because well uh it's just supposed to be cool um the logic is as simple as basically checking that these two proofs will kind of line up with each other and that's it and all of the actual verification of the recursive proofs happens for you automatically so um uh yeah so that's just a taste of this recursion api it's really nice and simple and i hope you know we'll see a lot of cool applications of recursion because it's been something to this point that's been really specialized and not really

available for developers to play with so uh that should be cool and this kind of goes back to i think a question i can't remember who asked it but um about kind of defining peer-to-peer zk roll ups well you can implement something very similar to this and you know it could run in a browser it could run on you know devices anywhere and you can call into it using javascript and so um this actually you can use you know independent uh uh of a snap you can you can kind of create these proof systems and so that's really nice and simple so uh with that i will stop screen sharing um

and return to the slides oh oh yeah what's up you good anna all good questions but we'll do that when you're ready well yeah yeah yeah um and just let's just wrap up here so uh there's a couple things we didn't cover one is we didn't cover how you interact with the mean of state uh for example like getting the current block height or like current timestamp to do things with time and that's pretty simple but we didn't cover it so you know sorry you can read the docs we also didn't cover the whole api

that's provided in the standard library for example group operations and operations with merkle trees which is really useful for kind of interacting with off-chain storage um and uh yeah so that's unfortunately we didn't cover check out the docs or you know future presentations of ours and if you're in the meena builders program or coming to boot camp see you soon and we'll talk about some of these things um and uh yeah so just to kind of put a pin in it or no no i'll put it in put a cherry on top that's not even really the right idiom but here are some ways you can kind of stay connected with us if you go to mediaprotocol.com.js i believe there is

a feedback form if you want to provide any feedback or help shape the future development of snarky.js um and otherwise we have our links on github uh where to follow us on twitter and how to um you know join our discord where you can come chat about snaps so thank yous everyone you've been a beautiful audience and um now we're gonna i guess do questions um also there are discord channels too so you can join the snap developers channel on discord and do stick around because we are doing

the closing ceremony of the ck hack right after this but we still have 20 minutes and i know that there was a lot of questions and a lot of them got answered but it might be interesting for our video viewers to actually hear some of those so even if there's answers on some of these in the q a potential wondering jason i mean i think jason and isaac you'll be able to pick out the really kind of good ones but i think it'd be great if we can hear a bit more let me answer one um just for clarity uh was it explained why bool is necessary instead of using a native boolean so isaac briefly touched on this it's just because the operations side inside of a snark are done differently

so a couple couple things are done differently and one is you instantiate a bool using new bull as opposed to javascript's new boolean so that's one and then secondly uh there's not turn standard ternaries are not supported inside of a stark so we have uh circuit dot if to to provide provide that as as isaac discussed i'm just going to take another question here um so this was i'm just going through questions in the q a a lot of them already answered but i'm going to try to add some a little bit of extra to them so jeff asked with tools like snark snark

js plus circom that's another tool there's a limit to the number of constraints uh with the was improved generator something like 1 million other analogous proof limitations here so um yes actually so there is a limit to the number of constraints um that you can use in a single method it's a bit like the gas block limit in ethereum so there's a limit to what you can use in one method but you can have as many methods as you want and that you know all have up to that limit and as mentioned by brandon you can also use recursion to have an arbitrarily large computation so

typically you know what a computation looks like is not a random giant circuit but something with a lot of structure that's kind of repeated and if you use recursion then you can um you can you can do this uh and you can even actually have arbitrary kind of structure too but it's it's a little more involved um let's see moving on um let's see so um fabrizio asks do you have to use the extra circuit size even if you did not use recursion um i'm not exactly sure what the question is but uh no you don't need to use you use what you pay you pay for what you use so um if you don't you know go up to the

max limit of constraints you don't you don't really pay for that um okay vm asks which hash functions are supported for verification on chains so um currently in sarcoges the only thing exposed is poseidon so this is a poseidon hash function that's used in mina and that's what you can use in stark jazz uh there is an uh undergoing you know there is planned work to implement um other hash functions that are more commonly used in other situations like shot 256 for example and that you know will eventually be easily available in snarky.js

um so uh james asks since this all looks kind of ready i'm curious what still needs to be done before these will work on mina so we're currently you know finishing up testing uh snaps and kind of you know making sure it's it's ready to be deployed in maina um and uh you know there should be an announcement sometime um you know in the not too distant future about you know what kind of times you can expect but there's nothing publicly announced yeah um let's see so anonymous asks is there a bridge over to ethereum this is a great question um there is a bridge so we so mina foundation

has been working with a theorem foundation and nil foundation uh on a bridge between me and ethereum which will enable mean a state to be verified on ethereum and that's really cool because it uses the succinctness of mina to just verify the full mean of proof and the full mean of blockchain in ethereum so you get basically a bridge with like full node security um which which is really cool um let's see okay uh jason are there any questions that you would like to answer i've just been kind of running through but you're somebody did ask um do i mean

snaps general uh we'll have a few different channels so uh there is a snaps general and there either is or will be very soon a snaps developer channel also on discord um [Music] all right so uh kobe asks what point in the develop compile deploy run pipeline would be catch invalid proof stay transitions like if you just print yourself money out of thin air that's a great question so when you basically when you try and generate the proof so when you try and run the

contract locally it will fail if you do something that's not allowed like for money out of thin air and uh you know yeah so that's kind of that but um if you somehow you know created a proof like circumvented what's going on in smart.js and created a proof if you broadcast to the network it would it would fail at that point because the network would see oh you're trying to put money out of thin air that's not allowed um someone asks for those of us attending the workshop this weekend what would you suggest we invest time into to prepare for it other than the exercises of course um jason is there anything you know you can think of suggesting for those who may be attending our boot camp

uh good question uh the setup that isaac did today as far as having vs code or your preferred editor in note 16 are really the requirements for it so if if you follow along today you'll be good to go for uh thursday um cool um let's see someone asks is it possible to develop on mina if we don't like js well yes as long as you like o'camel so if if you really want it you could use o'camel um to write your small smart contracts as well but snarky.js is our kind of primary um development uh platform

um let's see so someone asks for those who can't attend the work bootcamp can we expect more events in the future definitely no news on on what but you know stay tuned on twitter on our discord for any updates about more events as we roll out snaps you know we'll we will be doing a lot of um uh engagement with the developer community um to help out with building snaps um all right um i mean i can i can keep asking answering questions here um

someone asked uh for the reason that we use node.js could the hash function that hash functions be used so they're asked so i believe this question is if the hash function is available in node.js can it be used it's not js the answer is not exactly because the hash function needs to be needs to be redefined to work with the types of snarky js so it would need to be redefined to accept field elements or bool as input and for that we would need to you know you need to re-implement it either directly in constraints using snarky.js or um what we are planning on doing which is actually integrating it into our kimchi proof system itself so it's available

very efficiently um okay so francesco asks any plans to reduce block time and introduce deterministic finality that's a great question um it is something that you know where that's definitely on our mind there's no concrete plan um yeah that's in place to address that but um i i you know i believe you should uh uh stay posted on that because i think you know that will be something that um is is you know uh i can't speak for amina foundation but i believe that that will be something that's you know that will be important to them going forward

um okay oh anna yeah what's up yeah isaac i mean do you want to do one more question and then yeah i know there's some people asking kind of like if we're wrapping up soon so i think we're going to head over to the stage after that but maybe just do one more question perfect cool um all right so just having a look here um oh just curious what was the reasoning for o'camel as the underlying language for mina uh i have answered this question a few times in the past um i mean i think uh okay uh you know the real reason is amino was created by people like myself

who have their own history and uh you know abilities and whatever and um you know i guess uh my own history involves writing a lot of o'camel code um and that was kind of the the reason i guess you know realistically speaking that we chose a camel but um i think ocam was a very nice programming language and um you know good for writing uh secure code so um there's all sorts of reasons i can tell you that i think okamo's a good language but i think the real answer is it's what me and and the other initial developers like brandon were familiar with um

and yeah happy to use so it's worth also adding to that that's uh other ecosystem members chainsafe in particular are working on a node in rust right now awesome all right isaac jason are you do we feel good should we wrap up i mean you can actually just tab and keep going with more but i think no let's wrap it up okay so thank you so much for the mina session this is the last workshop of zk hack it's been amazing and i know for a lot of people this is

their first look into the snaps world and they're so excited you can kind of get that from the crowd very cool okay so um yeah thanks again for doing this session and people have asked the videos for this will be on the youtube channel as soon as we can get them there so ex we've shared the link uh let me share it again in here after a bit but for right now if you can head over to the stage i'm going to be doing sort of the zika hack wrap-up closing ceremony where we look at you know the six weeks and the prizes that some of the hackers have gotten so i hope you'll see me there

and yeah just remember there's a 40-second delay on that so if i'm a little like stumbly with the with the chat i apologize i'm not seeing your notes at the right time anyway see you soon you