 we are I'm actually trying to do some practical stuff like implementing a snark circuit to process a role of transactions so if you want to follow along you are welcome to yeah so if you want to install any requirements they are over here and this this link is public I do not buy a domain so you can use this one yeah yeah I created this due to the limits mostly going to be like me spending what's what how role of works and maybe creating a circuit for it life basically ZK or love is all about using snark for their not for their privacy expect for creating such improves so that we can verify lots of competition done off-chain you know on a smart contract on ethereum chain so for roll-up we basically do all the signature aggregation balance checks changing all the balances for the participants in world in earth transactions of chain and we batch all the transactions together and submit the snark proof as well as the compressed transactions on chain so as a so ZK rules are basically a layer-to-solution and unlike plasma we don't really have to worry about things like data being not available in plasma users have to continuously watch their coins so they can come they can be active in some challenges if anything bad happens right roll-up has no such assumptions so a snark proves the validity that the transaction that the computation done off-chain is actually valid right so it's a it's it's pretty simple so we have two actors involved in a roll-up chain there's a coordinator and there is a user so the coordinator basically takes all the transactions is like inputs and signatures on the users via RPC endpoint API or anything like that and he basically generates a batch and passes all the transactions to the snark circuit the snark does all the processing and emits the updated route hash and the snark proof so on on on an ethereum smart contract we maintain a balance mercury right so it's like the mercury and the leaves contain balances and accounts of all the users right and this this route hash of this mercury can only be updated by a snark proof right so as soon as the patch is processed by a coordinator he summits the snark proof on chain and the on chain verifier checks if the proof is correct and the proof is correct the new new route is updated in the smart contract right so yeah this is why roll-up seems really amazing to me so it has no exit games and it has no like this assumptions no data availability issues the transaction fees is still very very less yeah and basically we can create roll-up chains not only for payments we can do stuff like cryptocurrencies we can do stuff stuff like what fair winded like any any sort of smart contract right so it's basically a snark storage layer basically you can put anything you want you know in the leaf of the mercury and it will work right yeah so for the purpose of this tutorial sort of thing we are using circum and snark js they're basically JavaScript based compilers yeah and these are basic commands you can like hop hop back to them whenever it's needed we'll mostly need them every time we do a compilation and we create an input right so I'm just going to show how to create one one simple constraint which is like a arithmetic constraint we are going to see if a plus b equals c and create a snark snark proof for it right so so that we can go anywhere and proof and like proof to someone that this competition was done correctly time so it's pretty simple as as you can see just like create a template template is just like a circuit and the inputs they are called signals so every every variable is a sort of signal for you can imagine circuits like electronics circuits right so in electronic circuits also we have signals in inputs and outputs as well so here we are accepting three private inputs we are calling it a b and c and we have one one public input it's called c right and we create an output signal call out yeah and this this is that we are forcing a constraint we are basically forcing a plus b to be equal to see which is provided a public input so if so if we can basically prove that two plus two equals four without getting to know what what the first two variables we don't need to know that they were two and two yeah that's what so they can be one and three or they can be three and one we don't really need to know where so this basically creates a constrain for addition we can do one for multiplication as well like this it's pretty simple and whatever we need to give us a output we just force a constraint and we assign to the output variable so as you can see it's pretty simple right yeah so as soon as we are done with the so is anyone following around or should I wait yeah cool so if anyone wants to compile it and generate inputs and so first of all we from the circums circuit we create a compiled version and it's called it's a it's basically JSON representation of the constraint in the circuit right and then we basically have to create inputs so the inputs for this would basically be a PC a BDNC so we just put that in a file I can show you that part yeah so this thing basically is the yeah so here we just pass the inputs 2 4 6 and 24 and we create an input right which has all of these variables and then we basically when you have input or json ready we create a we calculate witness which is like the inputs we are going to provide to snark that what that input basically satisfies all the constraints defined in the circuit so if if so if this command throws an error that that basically means your inputs not not going to pass the snark survey that something is wrong with the input and this is the setup it's currently only on your laptop so it's it's going to be pretty unsafe and then then we can create a proof and we can do snark just verify which is basically tell you the proof was right or not so if it displays okay then it was good if it says invalid something went wrong your input did not satisfy all the constraints defined in the circuit right yeah yeah so growth is like growth 16 this is the most efficient prover there are some other options you can do that such protocol and it's like I guess I don't really know I've always been using this one right yeah yeah so if you got if you guys want I can you know run these and show you but it takes quite a while to run all the blues right so I'm gonna hop up ahead if someone wants to run I'll be happy to you know debug if there's any issues cool so we so we are going to verify a EDDSA signature next so so in snarks is it's much more easier to verify a EDDSA signature than Ethereum or Bitcoin signatures because it requires less lesser number of constraints right so so there's a library called Suggam and they export a template it's called EDDSA minc verify have you heard so there's a hash function called minc because sharp 256 is like way too costly to use inside a snark so this is like a so minc uses much less number of constraints and it's therefore the proven time is low and for the purpose of this workshop this this level of security should be just fine right so it's very easy to use this template we just like pass the from the so the you know for a EDDSA there are two parts the X coordinate and there's a Y coordinate right so in the verifier we call the we send the X coordinate and here we send the Y coordinate and this is part parts of signature and this is the message that we want to check the signature against right so if it all is a calculate witness things run smoothly then your signature was basically correct right yeah the security is not widely researched yet so we will generally tend to avoid this because it's not the security is not really proven at the moment but it's not it's not broken it's it's not proven either so we so people generally tend to avoid it but it's fine for the case of workshop is there any other one which works well it doesn't work pretty good yeah that's all right it's not a solution what is the what I'm trying to make private because this is already kind of it you don't take any information in this we are just trying to verify a signature inside a snap you're not trying to make things private in this circuit yeah yeah because while doing a while verifying for from for roll up we'll we'll have to verify if the if a transaction submitted by a from address is actually signed by yeah cool so yeah the next part is like very fun like creating a miracle route for given leaves and yeah so that's why here we basically have two or three variables it's like part to root is basically the leaves in the miracle proof right and part to root position is basically binary vector so if so if the leaf so let's say there's a leaf at index 0 in part to root so part to root position at index 0 will basically have 0 or 1 0 means that the leaf is left 1 means it's right right so we'll see how that's used in later this is a single so multi-mc 7 basically creates hash if you provided inputs the first parameter here do is like the number of inputs you want to give it right so so yeah so if if part part to root position is 0 the miracle the first input to mc becomes the leaf itself right so this is how the binary vectorization works so so if if this this thing is 0 then the first input becomes leaf and because this thing is also 0 the second input becomes the sibling right and if if it's one then the first input becomes part the leaf and the second input becomes the actual leaf that you want to prove the path for right doesn't make sense so we then then we basically just do the same thing but over a loop right and like we can just basically copy this part over here and as soon as we have filled all the all the inputs if we if we do mc root dot out which is basically this this template dot out so it basically gives us the hash of the leaf right so whatever we have passed passed over here doing dot out over it gives us a hash so if we give like two and three dot out gives us a hash of those two inputs right so it's basically used to create hashes of leaves so that we can get a model tree right yeah and this part is checking the existence of a leaf in a tree it's it's it's also pretty pretty basic we just like take the paths and we assign elements like we did over here over here and this part basically tells us if the dx root that we have given if the root given over here matches the root that we have just created inside the snark right this was basically designed as a workshop so because of bad internet connections I tried to skip it but so so people basically had to enter this values but I can show you the snark circuit over here so yeah so just to show you the circuit whatever was was was missing is present in our in in this file it's so it's present on GitHub I'll give off the link in a while yeah so it's a sample circuits are present here right so whatever was missing over there is yeah so so I'm just going to do how deposits work how we draw work in a lot of chain right so basically the operator gets all that transaction and it let's say a snark path supposed to be up in 10 transaction right so the operator if he if he has 20 transactions he picks up top top 10 according to the correct nonce and he provides it to the snark circuit and we go from root 1 to root 2 and we submit all the transactions and the sample on chain so yeah this is how state transitions work for snark for roll up right so the account is basically like this the x-coordinate of the public the y-coordinate the balance nonce and the token type right and the leaf is basically the hash of all of us right but for the workshop we are just going to do balance only so no no nonce not open type but we can in a roll up chain we can actually have multiple tokens trading just simultaneously and the operator can accept fees in any or all of them right so yeah so this is how account looks like so it's a key balance nonce and type and the balance history is this right so we change the account route every time we submit a batch on chain right yeah and in a transaction we have from we have from from index which is like the leaf index in the mercury and we have two address so deposits to roll up chain like that they are pretty interesting so what we do here is deposits happen totally on chain right so as soon as someone deposits let's say 1 1 8 it's pushed to an ally as soon as someone deposits someone as a second deposit both the deposits are hash together and they are they are like a tree is created right so yeah this is the first first first deposit second deposit and it's the hash then as soon as we have a third deposit then we wait for a full deposit as soon as it's done we create a hash and we combine them together so what so what what what we can do is whenever we want to include the deposits in the rule of change we just pick up the latest route and we attach it to the existing balance tree so so we create a whole new suffering and snuff proof is created which which basically just proves that this this this leaf was empty and the deposit tree has been inserted over here yeah yeah so this was the old accounts tree and now the new algorithm becomes that that whole thing and just a deposit rule gets placed over here right so we're drawing all the drawing is also like a simple state transition like transfer state state transition so like people just send their tokens to leaf index zero which is which can only receive tokens leaf leaf leaf number zero cannot actually spend any token this is defined in the snuff so people have to do a transfer to leaf index zero and then they can go on chain and then they can prove in the latest Merkel route that it did a transaction to leaf index zero and they'll get their token back from the deposit right yeah yeah earlier you had mentioned that the CK-Roller was needed to make data build the assumptions but don't you need data build the assumptions to be able to properly process a withdrawal from the market tree because you need to know these are the tree trees so so with the pre-snuff proof that we submit on chain we submit a condensed form of transactions right so using that any one can come in proof that like basically all the other transactions that have been processed in the latest snuff are present on chain so the data availability is same as Ethereum chain yeah I just missed it in the beginning it seems like just this example really balances or there's just a transition function from trees to trees and you're trying to show that basically the trees that were produced are correct or what does that do the constant balances yeah so so in the state transition function right which is like written inside us now we basically say that let's say Alice is transferring fifty dollars to Bob right so in that we basically check if Alice exists in the tree if he has fifty dollars to spend and then we basically change his let's say Alice had hundred right so we change his balance from hundred to fifty and we increment both balance if he exists in the tree from zero to let's say fifty and we update the snuff snuff muggle rule yeah so this is how the state transition happened and we submitted the updated does that answer your question yeah so it's not really about it's pretty general yeah it's pretty general yeah you can basically store anything inside the leaf and write a state transition around it with some condition yeah with some condition anything that can be yeah so this is basically just like doing all the checks inside the snuff I think I'm going to skip all the steps and we are going to go to the final circuit so I can show you how it's actually happening for for writing multiple non-transactions you just do the same thing with the following for the number of you want to process right now it's only one but I have a section over here which is for multiple you can check it out why do you do it for the intermediate yeah so yeah so often is it there it was a previous batch so the thing is as soon as we process one input we should update the accounts tree otherwise if a leaf is changing multiple times inside the same batch then it may be able to double spend right so let's say in a batch Alice was Alice had only 50 bucks and she was like able to get both of those transactions in the same batch so if we don't update the worker root after processing every transaction then when the snuff is processing the second transaction of Alice the circuit will never know that a previous transaction already spent the 50 bucks that she had right yeah so this is a pretty standard we like take the inputs as like the previous account routes the intermediate route since this is just for one transaction so it has only one intermediate route you wanted to do multiple this would be an array and here is a these are all the accounts these are all the balances the balances in an in an array and here's where you provide all the transaction input right which is like the sender puppy sender balance receiver balance among other sender signatures and the proof of existence for sender and receiver right and we output the new accounts route after processing everything right cool so in the so since I guess part 3 we did a part where we in part 2 we did a part where we showed the existence of Merkel leaf I guess yeah leaf existence right so using this template over here yeah so using that we are basically going to prove that a sender account exists in the previous account route which is provided as input right so we just pass the puppies and balance and yeah we do the same thing for all the senders given in the batch right and then we just do a simple signature check that if the sender has actually signed the the message yeah and then we create a new leaf hash so the leaf hash previously contained like a puppy balance which was 50 then after after spending 50 is leaf will look like puppy and zero so we need to create new hash for this and we need to update the accounts route so this basically outputs the intermediate route right yeah and using this intermediate route we basically check if the receiver exists in the tree or not if we exist then we credit the receiver with whatever amount was sent by the sender yeah yeah here's where we debit the sender and this is where we credit the receiver and then we basically just like create a new new leaf for the receiver again and we update the route for it right and we just out of the final route as the newly new new route of the new Merkel tree with updated balance right and then we just like then we run the new commands and we get a proof which which which we can submit on change the many five transactions right so that basically proves that the state transition that was done off scene was valid and we push the transaction on action on scene for data so where was the check that the transaction has corresponds to the action test where was the check that the transaction has the previous transaction sorry the transaction we have called matches the leaf the account information the previous account information matches the leaf yeah yeah so basically if the so let me rephrase the question and you can tell me if I'm correct or not right so you're basically asking if the accounts route submitted over here if it had if it had the correct balance that Alice gave me or not if it did not then when I submit on chain the the previous road hash which is submitted on chain won't won't match with the input submitted over here right so it has to be changed that makes sense yeah so I wanted to like like create a smart contract via this like generate verifier call and this basically creates what the proof that we need to push on chain right so if you guys want to try this out and maybe we can do that now yeah are there any questions with this yeah so yeah so this is the link of the workshop workshop now so yeah so yeah so So that basically assigns the signal value and case of constraint. Yeah, so let's say there are two signals, right? Let's say there are two signals, A and B. And I want to put the input in C and I want to make sure it checks. Like, there's a constraint that C should always equal A plus B. At that time, I do the angle bracket and equals. So, there's a link in this workshop which basically directs to iDent3's blog post on how to use SNAP 3S and SIRCOM. That basically has an explanation on how to use all the operators. And you can bloom this repo for all the code base, all the sample circuits and input of JavaScript files. So it's going to be up after the conference. Okay, cool. He has the next idea. We can actually include multiple, we can use multiple circuits from a single circuit. So for multiple transactions, I just had to put a for loop for the for single transaction. And had to create an intermediate loop after processing every leaf. It's just putting up for what it was. And the circuit size gets pretty big. That's why I did not. It takes like 20, 30 minutes. What is the size of the proving key for many, many transactions? It is pretty big. I don't really have the numbers right now. But yeah, there's a link here if you want to see that. So if you want to check how multiple token accounts work, there are test cases and input files over here. Feel free to type them out. Oh, it's already pre-generated on GitHub? Yeah, yes, they don't matter. Yeah, so if everyone has the links, the library that allows us to verify the proofs in Ethereum. So in the last step over here, if you burn this thing, then it will create a verifier, a solidity contact point. And then you can just deploy and remix it and check the proof. So it's part of smart savings? Yeah. Yeah, so if you want to follow along, it's pretty simple. All the code is present here. You just have to rename most of the files. So if you just clone this, then it should work pretty well for you. And this link is present in requirements over here. Yeah, so I can maybe do this part quickly to just show how it works. So if you just create a file called circuit.com and copy paste this code. And then we can move forward with it. I have this file. So I have this file ready now. I just have to do the compilation over here. This basically creates a compile. It's on file. It basically represents all the constraints. Yeah. And then I can just create inputs. This will be the input. It's the auto JSON for me. This is basically the way it was A, B, C, and D. So just to remind you, we are putting a constraint that A plus B should be C. So if calculate witness runs correctly, which basically means that we are running the input that we created against all the constraints in the circuit, then it basically means that the proof which is generated would most likely be correct. I can try changing the input and see if it breaks. So if I change any inputs and A plus B don't equal the C thing, then it will basically show that the constraint does not match. So you can do the same thing for verifying the EDDSA signature and doing the mockery proofs, like proving that a leaf exists in a mockery and creating a mockery and all of that stuff. So I'm going to try processing a single run action over here. So in the file structure, if you go to the fourth folder called single case, it basically has the circuit and the... They calculate witness. Is there no output? Yeah. Where does it go? Yeah. So it creates a file called witness.json. And it has all the public and private inputs. All the public inputs. Yeah. Well then, same as the input json basically? No. So it has all the input. json is basically all the inputs you need to provide, you need to provide to calculate witness to create a witness. It's created witness. Can you open it one more time? Sure. Is it? Yeah. And so... So it has... Just so the numbers that are listed here, they don't need anything like whatever, they're kind of like random, but the length of this thing is short. You're basically always saying that the length of this thing is short because it's... I just don't understand. The length of this array of whatever, five numbers, because the circuit is very simple. Yeah, exactly. So for a circuit with a larger number of constraints, the witness, the file would also be large, because it depends on the number of inputs you're getting. This is all kind of new to me. So the constraints that are there versus the computation that happens, how does that affect the size of this thing? If the constraints are... For example, computing, you should have, there's lots of computation there, but there are very little logical constraints about the size, the assertions that you make on it. Here you have assertions about the arguments, but then you may produce bindings inside of a circuit to bind new variables and say that also this... Does that make sense? When you make circuits like this, there's a lot of constraints on things that matter versus just raw computation. So FD, do you want to know it? Okay. So let me repeat the question. So what are you trying to do to get an intuition for this idea of constraints, like how many constraints matter? Versus raw computation, I can say something like the LED binding in this language, where it says LED A equals hash of these things versus A plus B equals C is like the assertion that the individual is going to follow. So you want to see what's different in the witness calculation in this case? Yeah. So okay, the witness calculation is... Yeah, it's just like... I mean, in some languages it takes longer, but that's just going to come very long. But like when you get off the road, it's always... Yeah, so like if we had a text, it would spend like 0.0001% of your time counting the witness and all the rest of the time. Yeah, so we can do the same thing. We just have to write a new circuit that we defined in the previous parts. And we really have to like check the sender, the receiver's key, the balances, and we need to update the amounts, right? So I'll just move to like processing a single transaction and we can... You guys can try out the rest parts and I'll be here to help her out, right? Website. So I'll just like copy the sender and I just have to run the same amount and I just go through how to create the inputs for this and then maybe you guys can try it out. Yeah, so for this workshop, I basically created a script which generates the input for your circuit. So we basically here create a new private key and we declare it that it's Alice's private key and we create a Bob's private key, right? And we have Alice's pub key. We have a Bob's pub key and we are basically using these two helper files from Surcountable, yeah? And we basically create an account for Alice and we create an account for... and we hash the pub keys and the balances together as it was during the tutorial, right? And we use Mitzy and then we create a leaf account for Bob and we create a leaf hash for Bob and we basically generate the initial account route for both these accounts. So since it's only two accounts, we just need to hash them together and we'll get our mark and route, that's right? Then we need to do a simple round action and from Alice to Bob and Alice needs to sign that round action. So we send our private key over here and we get a signature over here. Then we generate a new account. So Alice is basically trying to send 500 tokens here. Alice in the previous state route had 500 tokens and Bob had zero. So after transferring Alice should have zero, right? So we create the intermediate route. As soon as we process a leaf, we need to create an intermediate route so that Alice is not able to spend the 500 tokens she spent earlier again. So we create a new leaf hash and we declare it as the intermediate route. Then we update the Bob's account with the money he got from Alice and we create a leaf hash for it and that's the final route and we pass all of this as inputs. We pass all of this as inputs to the circuit and we dump all of this data in input.json file and when we basically run Calculate Witness it uses these inputs to generate a witness and later we can use the witness file to create tools. You want me to try out or do you guys want to do it? I can try it. So it takes a while because this circuit has not many constraints than the previous one and it basically uses other circuits so every signature verification has its own constraints checking on Merkle route has its own constraints. So it takes a while. This will be the input file for us and if I try to change the input or witness after this it won't work. So you were saying that like, you know, SHA 256 doesn't apply well? Yeah, so it just creates a lot of constraints. But in theory like, but oh, but what you're saying is that you also said that like, you're just saying that the compilation is the only thing that really takes a lot of time. Yeah, the proving. So what if, is there, I guess what I asked there is that like, assuming that you did it once, is there some way of like, some roll up jet where you just like, you did that one time and you made a circuit for it but you don't want to prove it every time. So this is, I guess you can never mind. So you basically have to create a proof every time you create a new batch, right? So yeah, at most we can do, we can like, parallelize it and like, using like vanilla GAs we can predict if I process this batch of transactions, the new model would be this and I can in parallel start processing next batch while the proof of previous batch is being created. So I created the proof before coming here because it takes a lot of time. So if you guys want to try it out, maybe you can run these commands. I can try running them but it takes a lot of time. So it depends on the number of constraints for this, it won't take like, it will take like two minutes. Yeah, so it's fine. So this tested setup is basically one party right now but I guess I didn't think people have been working on doing MPC with Snarky as well. So yeah. What is MPC? So it's like multi-party competition and a lot of people don't run the setup and they're supposed to discard the toxic waste. So let's say 10 people participate and even if one of them is honest, then it should be fine. And because we are the big participant over here, we can basically create false proofs but if we had multiple participants like let's say 100 to 100, then it should be fine. Yeah, so it takes a lot of time. So if you guys want to try it out, I'll be here to help out and I'll be here to, if you have any questions or stuff. Yeah. What about the debug tools? So if I'm running my instrument and I see that it's on the inside. I think there's a log flag. So you can actually write logs but I guess people are still working on the compiler. So I guess it should be out soon. It's everyday. If you wish to switch the proof system like Sonic or some other one, which of these libraries would you use and which would you have to throw away? Is there anything that you would reuse if you change the coding system? I guess we'll have to create new libraries for the new proofing systems. Yeah, so I guess we'll have to create new ones. So the compiler is just like going from Syrcom language to the R1CS constraints. Yeah, that part can most probably stay from there. If there's a new proofing system out, you can maybe use that part. It's likely that there's some different optimization factors that you have but the optimizations are coming to 7. So you can still have a lot of time to do stuff on the R1CS. But if you want to do start, it's a different story. And if you want to do what I think the clock is a little different from the R1CS, then it's a little different. If you have any questions, why can I vote? What's your name? There's a bunch of groups in the Y4. There's a bunch of stuff and we have been working on a thing called roll-up NC. It's a roll-up non-custodial. What it does is that it basically does not push the transition on chain. So when you try to push the transition on chain, that basically limits the amount of transition that we can process to the amount of transactions that can be submitted in our block. So we are limited by the gas. But if we don't push the transition on chain, then we can process a lot more transition in a single batch. So this is for things like if you want to make a leader on a roll-up chain and it's placing fast. It's all like that. I think I may be finally understood. Maybe not. But what you said about the parallel competition, so is it possible to put a proof constraint in this language also? Basically, what I would say is these arguments satisfy, let's say you wanted to run something in parallel or whatever. I had some setup which is like, yeah, the arguments to this thing also satisfy this relationship between each other and I wanted to express the fact that there is a proof of this. I guess what I'm saying is that you run around in a parallel and say you had some really expensive things that you wanted to express that it was longer to match up if you did to create one circuit between the two of them. Rather than having one function that describes something really complicated, you can break it up and then basically you don't save any time to break it up into smaller pieces that would compose to a larger circuit or whatever. You have times of constraints that are all related to the same data and maybe some of them could have run in parallel. Do you save any time by splitting up off into different circuits? Yeah, so I guess we are already splitting them off into different circuits. So yeah, that basically does not save us much time because the constraints of those circuits are combined and they are taken into when we generate a proof those constraints are still added to the constraints of the horizontal circuit. There is no such thing as multiple circuits if you run one circuit at a time. There is kind of this idea of putting multiple mass things so that the snorkel can be snorkeled. I think that's for you. Are you just like you had some conditions about the data that some of them are dependent on or something like you had some relationship between all of them. Yeah, so I guess you can basically let's say you have a batch of parameters. So even before the circuit creates a proof of them you can basically say if all the parameters in the batch are correct then this will be the new group and you can use the new group to run another proof and null of that. So that's very fine. So if the first proof is like if it runs perfectly then we don't really have to wait to like start the process or anything like that. How expensive is it to verify a snorkeling in a snorkeling in this 40 school season? Yeah, it does.