Mina Protocol 🛠Building zk-rollups with Protokit
ETHGlobal·Wed, Oct 9, 2024, 12:00 AM
Join us for a Protokit workshop! From November 17-19 2023, ETHGlobal welcomed developers from around the globe to take part in shaping the future of Ethereum at ETHGlobal Istanbul. Over $600,000 USD in prizes were given away at the prestige Istanbul Congress Center... thanks for an amazing weekend hackers! ----------------- Follow us: https://x.com/ETHGlobal?s=20 Check us out: https://ethglobal.com/ Email us at: hello@ethglobal.com
Transcript
[Music] hello everyone welcome to introduction to Proto kit aka the Mina protocol presentation on how to build ZK rops my name is mat I'm the one of the co-founding engineers behind Brit and today I would like to show you how you can build your own ZK roll up with little to no learning curve on the Mina protocol um you can see our socials right here so if you have any questions um please write them down and ask them afterwards because I have quite a lot of content to go through so let's get started um before we um get to the actual zarola building section I want to make sure that we are all on the same page when it comes to um understanding of what zero knowledge actually is so um let's get into it so the first question I want to answer is what is a ZK proof so ZK proof is a mathematical proof of computation um that is is done on top of using like public or private inputs and it results into a public output um what can you do um in a proof of computation so you can verify signatures you can verify Miracle proofs you can do addition subtraction multiplication or uh for example hashing using poson and a lot of other cool stuff that can be mathematically proven um to compute a ZK proof you need to use a proof system the proof system that we use for our prod kit is called kimchi and it's the same proof system as the Mina L1 is based on um to generate the proof you need to execute something that's called a circuit and the thing that we'll be looking at at the next slide is a ZK DSL written in typescript called OJs that allows you to write circuits in typescript which you can then compile and generate a proof of the computation that you have defined so um when you compile a circuit you actually get two artifacts so you get a prover key and a verification key we'll see that later um and how it ties into building your own ZK rollup the most important part of why you should even care about proving your execution is that it allows you to run the execution once generate a proof and then anybody who wants to verify the result of the computation can cheaply verify the result without having to recompute the expensive computation again so this will be very important when you for example try to design a blockchain with a consensus mechanism where all the validators have to revalidate transactions when they're for example bootstrapping or simply participating in network with a ZK proof they don't have to rerun the transactions again they just have to validate the proof of applying the transactions by the person who created the block so um the zero knowledg of a proof comes from the fact that the computation can be done on two kinds of inputs one is public or it could be also private so when the verifier is verifying your approve they have no access to your private inputs only to the public results of the execution um I've already mentioned OJs so OJs is a typescript library that allows you to write circuits there are a couple of important Primitives exposed it's called for example ZK program as you can see we start with defining the inputs and the output types of the program and then methods which are the actual computation that we care about um every method can has can have its own private inputs and the the f program is very simple it's basically a program that proves a transition from one counter to another counter um and it only allows you to perform the transition from a hash of a number to another hash of a number if you know the pre-image of the hash right so just to go quickly through it um line number 10 we are hashing a private input a which is a un 64 um then we are ensuring that the hash that we have created from the private input of the number matches the public input of the number which is the current State the current hash of the counter then we increment the RW number so a plus b that's line number 12 and then we return the new state which is the hash of the addition that we have performed so we have a hashed counter and we prove that we know the current value of the counter and transition the state to a new hash of the counter so how do we uh run the circuit so first you have to compile it as I've said that gives you a prover and a verifier key the compilation is itself is pretty expensive so depending on your Hardware we're talking at least like tens of seconds um then we Define some State variables that we will Feit into the increment method and line number seven we actually run the increment uh method of the circuit this is another expensive part because you actually have to mathematically compute the proof behind all of the operations that you're trying to do so you can expect another like tens of seconds to actually generate the proof then we get a result which is our proof of increment um that proof can be verified very cheaply using the verification key we see that at line number 13 and then in between we can just keep track of the uh State variables that we need to so very simple we've just written a counter circuit we've seen how to compile it how to run it to get a proof and how to also verify the proof another important aspect of the kimchi proof system or actually the recursion layer on top of the kimchi proof system which is called pickles is that all of these programs and all of these proofs can be recursive so um you can write a bunch of ZK programs and they can compose with each other right so this allows for example for Effective parallelization of your chain so um later we'll see how to write the ZK rollup and we'll go through like um what actually happens behind the scenes and we'll see how we split the execution into multiple parallel proofs so we can have increased efficiency using recursion um recursion essentially means that um the The Bu like the mathematical logic that's required to verify approve is implemented in the circuit itself and um that's pretty much it so how is this helpful for blockchains um what is a blockchain like that's the first question we need to understand it's basically a distributed database with a consensus on the latest state so nodes execute user transactions and a transaction is just an authorized intent to perform some State transition on top of the current chain data that's like every blockchain out there it's applicable so um after a block producer runs all the transactions on the behalf of the user the transactions are then bundled into a block and the block then signifies the new state of the blockchain so if you want to verify that the block and all the transactions in it are valid for example on ethereum or on any other non ZK chain you have to rerun all the transactions this is super expensive and it means that you need like you have pretty significant Hardware requirements to be be able to do that you need to store all of the data of the chain um and you need to have like a BV CPU to rerun the transactions um so as I said High Hardware requirements which means uh lower decentralization so what mea is differently as nl1 so the entire protocol is like written using zero knowledge circuits so it means that whoever is participating in a Mina Network once a Blog is produced and it arrives into your note or into your client you don't have to rerun all the transactions again you just verify the block proof and you can be 100% certain that the person who produced The Block did everything that they should have done correctly and they didn't try to cheat by let's say double spending or other common attack vectors so thanks to Mina's recursive proof design a block is a simple recursive block proof which means that that the blocks can be verified cheaply and quickly without rerunning the transactions so um let's now talk about about um Mina's native Elan smart contracts and how they tie into the recursive proof design of the Elan protocol so smart contract Zina you have to write them using the OMS Library There's A Primitive called smart contract um smart contract is just a circuit like the ZK program we have seen before that runs on your client so literally in your browser and proves its own execution so you don't need a Blog producer to run the contract anymore because you run it on the client side this means that um like the blockchain can effectively scale pretty well because you don't have to do all the computation on the Node side but all the users do it for themselves that is a pretty significant Leap Forward I think when it comes to design of blockchain so they're executed of chain as I said on your clients um the not operators don't have to execute them and what does mean means is that if you run the smart contract of chain so you run the contract on your device the only thing that you have to send in the transaction to the L1 itself is a list of state transitions that you want to apply to the global chain State um in the concept of the L1 those are called account updates the account updates are then authorized by the proof of execution of the contract or they can be also authorized by signature but um that's less interesting um then the blog producer only verifies the proof of EX execution of the contract and applies the changes to the chain state that need to happen um on DL one after the block producer applies all of these account updates or the state transitions you end up having a new block which has a new Global chain State those were the good parts but now we'll talk about a bit more about the let's say the design limitations of this approach um basically if you have two clients or like everybody in the room would try to do a transaction to the same smart contol ract and they would be using what we call preconditions which we'll explain later um they would essentially run into a race condition where they try to updated the same state but the proof was um calculated on outdated state so it's like a race condition all right um here we have the same circuit as we had for the ZK program but now it's written as a as a smart contract so the first thing that we see is we Define what the on what like what kind of onchain state do we want to store so so that's line number three um smart contracts allow us to store eight Fields word of data on chain itself that's about 8 times 255 is bits of data on chain um this is a pretty severe limitation that uh we have to engineer around and we'll learn how to do that later um again we have to define a method to interact with the with the state of the program or the smart contract and again it's an increment um that increments the counter or the commitment to the public state only if we know the pre-image of the of the number um the most important part here is line number nine where we um so line number eight we fetch the onchain state by doing this commitment get and then line number nine we are doing an assertion in the proof itself that results into a transaction precondition which tells the block producer that hey I have done this proof and it was done using this onchain state because the onchain state becomes the public input and this is where the race conditions come from um if multiple users are running the offchain proofs in parallel on their devices and they use the same preconditions um only one of them will end up having a valid transaction because the second one will get invalidated through the precondition or the commitment to the on chain State this is how you can um send transactions to Smart contract Zina it's super super simple so you just need to know the address of your deploy contract then you send the transaction specifying the fee payer you execute the method with the inputs that you want and then you'll have to prove the transaction and send it um as we can see running the increment on increment method on the counter resting to several account updates and the account updates looks simply as the follow so there you have the address then the preconditions to the onchain state and then State updates since you are updating the onchain state plus of course the proof authorization um this is like a pretty straightforward diagram I believe of how the uh smart contract layer looks like so at the bottom you have what happens on the client at the top you have what happens on the network on the note so let's start from the left LS executes counter. increment that gives us an array of account updates which are authorized by approve and then sent to the network so once the list of the account updates gets sent to the network um what the blog producer does it iterates over all the account updates tries to verify the proof attached with every re account update if it's valid then it also checks the preconditions and if all of these things end up being true then it applies the account updates to the state so therefore you have a transition from the initial state to the resulting State on the L1 now let's talk about circum weating the storage limitation of eight fields in the smart contract so the reason why the limitation exists in the first place is because when you write um zero knowledge circuits they have this property which we call they have to be fixed size so it means that you cannot have Dynamic size arrays because what a circuit is is essentially just the trace of execution and the trace of execution needs to be the same at compilation time and execution time so if your input size changes Therefore your Trace changes as well so since because the trace needs to be fixed or static size the storage which you can work with needs to be fixed size as well so what can we do about this so first of all you cannot have like key value storage like this because that would be dynamic size you can have a storage of a public key to you 64 like you would have in an erc20 contract to store balances um however what you can do is you can start using Merkel trees and store only the root hedge of the Merkel tree in the smart contracts public uh storage so let's go through what is a Merkle tree so Merkel tree is a cryptographical data structure that allows you to verify that certain data is part of a larger data set um and you can do that using meracle tree Witnesses so if we apply this concept and we take a meracle tree and start using it within our uh smart contract proofs we can circulent the um storage limitation of the eight fields and we can have essentially infinite State as long as it fits into our M tree so if the tree is is tall enough we can have essentially unlimited state so um instead of storing counters for every users we can store a commitment the tree of the data that we're working with and then the increment method of the counter would have to get the commitment therefore the rul of the tree um it would have to verify that the data we're working with the actual counter is part of the tree and then write the changes to the tree Itself by updating the root of the tree and storing the root has on chain again so this is how you would actually like update the update the Merkle tree you would have to um add the numbers together as we've done before and then you would have to compute the root hash of the Mer tree by using the new counter value so pretty straight forward now we have to go back to the design limitations of preconditions we were discussing before so since now everybody is working with the same Merry of data they have to work with the same root hedge of data so if there are two clients Computing something or trying to update the data concr only one of their transactions will be will be valid because the second one will get inval validated due to preconditions so again preconditions pointing to the root of the tree causes issues to users transferring causes issues there we go and um that's a diagram basically showcasing the uh the prond condition interaction so we have Alice that's trying to execute counter that increment um some offchain storage component which stores the entire tree and the actual data provides the data for Alice to do the do the computation in her proof that gives her account up updates which tries to set the counters to a new new root hedge or new state but it also has preconditions to uh to the previous state because we were reading the existing counters of the users so um those were like the good parts and the bad parts of the one smart contracts um me and my team um Rafael who's sitting in the crowd there we wrote a library that basically allows you to write your own ZK rollup where you won't have any of these concurrency is issues State limitations or anything of that of that nature um it's very simple to get started with your library you just have to like clone the start kit um and read the read obviously so what is Proto kit um proit is a t script based framework for building ZK chains um it's not using another ZK VM instead it uses a very custom usage specific um zkm um it has a hybrid execution model which means that you can have both offchain execution and onchain execution therefore you get all the benefits of the L1 smart contract plus custom onchain behavior um of chain execution means that you can do client side ZK proofs therefore all of the rollups are privacy capable or privacy enabled um the execution of the protocol that powers your ZK rollup is end to endend proven same as D L1 so therefore if there's a centralized sequencer that's running the protocol for you um you don't have to be worried about the sequencer being malicious because all of the execution is proven exactly as it should be um the framework itself is very customizable we try to write it in a way that doesn't force people to use um certain libraries or certain techniques or if you don't like the RPC Library we created you can just plug in your own which makes it very flexible um I think that the framework has virtually no learning curve assuming that you've built with the smart contracts before or at least you have some typesc screen knowledge or existing solidity knowledge so should be pretty easy to get started and get building which is important for hackathon so let's build your own ZK rollup so um recursive ZK rollup is again just a series of recursive ZK circuits we've seen ZK program before ZK rollup is just a lot of ZK programs and we provide the interface to make it as simple as possible for you so you can focus on building your app instead of building infrastructure every user transaction in the rollup is essentially running a ZK program that results in state transitions same as the account updates and we prove all of that for you um if you want to do this on DL one with the smart contracts um there are some building Primitives for like sequencing or like mle management but you still have to write your your own circuits so with RIT you can build zero knowledge interoperable and privacy preserving application chains or ZK rollups with like no learning curve um you can roll own ZK Rab in a few lines of code um and one thing that I want to mention is that if you write a ZK rup not a ZK app or dl1 smart contract um it's going to be a superet of what's possible with the L1 smart contract so you will preserve all the Privacy features of offchain offchain execution and have new features thanks to onchain execution um let's talk about a bit more about um what the Z LS are made of so we have the runtime which is replication logic we have have the protocol which is the underlying VM that handles uh the circuits for Block production transaction fees Etc and then we have the sequencer which contains modules for like the men pool orchestrating the blog production or setling your all up to dl1 all right um so what kind of features can you expect um we're hoping for like a supercharge developer experience but like that's for for you to tell us uh what you think um it's you can use like a bunch of reusable modules so it's super easy to create a composable ecosystem where you just use mpm install to install for example runtime module um you won't have any data Ras conditions thanks to the fact that we have a sequencer which will sequence the transactions on chain on your behalf um you will have bottomless onchain storage not just eight Fields um you are still able to preserve privacy or anonymity thanks to the fact that we have the hybrid execution model um you don't have to focus on infrastructure structure instead you can focus on building your business logic um it works well with the established ecosystem wallets and it's not another zkm um and if you wanted to you could reimplement the entire L1 smart contract back end in the framework itself which is not something I would encourage you to do because it's pretty complex but like if you wanted to you could um you can add features that will be executed on chain much quicker than the L1 will because it's application specific and some of the more things like some of the additional things that we're working on is interoperability between all of these rollups because you don't want to have liquidity fragmentation or like Silo rollups and also data availability and these two topics pretty much come hand inand and are pretty important for like further decentralization of the rollups so um how does the life cycle look like for a protoid uh protoid rollup and a user transaction so at the bottom left we have we have again Alice she creates a transaction where she wants to transfer some balances she doesn't have to prove anything so therefore it won't take her several tens of seconds on the client side instead she does a simple signature and sends the transaction to the rollup operator itself then the Rob operator sequences all the transactions received from the user and executes them one by one proving the execution of every individual transaction and also approving all of the state transitions that resulted from the transactions this results into a block proof that block proof is then taken and settled using L1 smart contracts to the L1 writing your own runtime for your own zup is relatively straightforward it's essentially the same developer experience that you get from the L1 smart contracts but you have more onchain storage and you have onchain execution so this is for example how you would write a simple ERC 20 like module with the ability to transfer balances from one account to another um testing your ZK rollup is also super simple uh we offer something called the stter kit which I've already mentioned um you basically have to create your testing app chain from a runtime object so pass in your balances class start the start the app chain and continue like writing your tests um in the test you would obviously have to execute a transaction so the API is nearly identical to what you can expect from thean Smart contract um that was actually like one of the design goals to take all of the smart contract developers from dl1 and allow them to transition to zops with no learning curve so you sign a transaction you send it to the chain then you manually produce a Blog in your tests because you can have control over that and then you can read the resulting state of the transaction using our query API which returns you um the new state so um if you want to start hacking on Mina and you want to build your own ZK rollup um all you have to do is clone our stter kit install the dependencies start a sequencer that will start the example run times packaged in the into the stter kit plus you will also have to start a UI and get building the start is pretty op um it has a react tailin shat CDN based UI um and it showcases how you can connect to the chain how you can read State through our graphical apis how you can send transactions um and how you can connect to your browser wallet so all of that is ready for you to start hacking you just have to pick it up and uh get to work all right so um what are we're working on now so um we've built a bunch of tooling obviously for for ZK rups um now we are kind of like transitioning not just like not stopping working on the tooling but we're also focusing on the product side of things so we're building like an open treasury SL governance system for the Mina ecosystem itself or like for every um ZK rollup built with the protoid tooling we've also built a DEX called copen um it's built using protoid you can check it out it's a nice demo that runs in the browser completely even the sequencer itself and the whole chain runs in the browser um find it on Twitter check it out let us know what you think um the question is what would you what would we like to see as let's say judges or developers of proit um we would like you to work on the following things or any other ideas that you can bring to the table um we'll be here for the rest of the weekend to to help you build so the things that I'm personally excited about is things like nft standards stable coins Landing markets dispute resolution credentials name services or anything else that you can see in other ecosystems and we pretty much don't have it yet um you can find our website at p.de all the links to GitHub start a kit our Discord server where you can ask questions are there I would like to wish you all good luck and uh have fun and let's not forget about the fact that Mina protocol has put out a pretty chunky price pool of 20K so come and build thank [Applause] you
Automatic transcript — names and jargon may be misspelled.