-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Tutorial: Using zero-knowledge for a secret state #13783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@corwintines , can I have a review on this? It's a very long article (probably the longest I've written), but I think it would be a valuable tutorial. |
Can I please have a review on this? It's a long and complex article, but it's a topic that can't be addressed in any other way. |
This issue is stale because it has been open 30 days with no activity. |
Temporary; will be deemed unnecessary and removed with PR ethereum#14926
recent codebase update
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @qbzzt! Huge apologies for delay on this one, and apologies it slipped through. Super interesting topic, don't let the delay be confused with this not being very appreciated.
I pushed a couple small adjustments and got the path to build.. left a couple other small comments, but most importantly:
I'm having trouble getting this to work... Following the instructions I'm not getting much when I run pnpm dev
, just wondering if I'm missing something here.
Also a note about dependency versions that I personally hit a small snag on... unlikely something that would interfere with someone doing this advances a tutorial, but could be a nice touch to just mention the node and pnpm versions that are expected.
Thank you. I will replicate.
…On Mon, Feb 17, 2025, 5:21 PM Paul Wackerow ***@***.***> wrote:
***@***.**** requested changes on this pull request.
Hey @qbzzt <https://github.com/qbzzt>! Huge apologies for delay on this
one, and apologies it slipped through. Super interesting topic, don't let
the delay be confused with this not being very appreciated.
I pushed a couple small adjustments and got the path to build.. left a
couple other small comments, but most importantly:
I'm having trouble getting this to work... Following the instructions I'm
not getting much when I run pnpm dev, just wondering if I'm missing
something here.
Also a note about dependency versions that I personally hit a small snag
on... unlikely something that would interfere with someone doing this
advances a tutorial, but could be a nice touch to just mention the node and
pnpm versions that are expected.
------------------------------
In public/content/developers/tutorials/secret-state/index.md
<#13783 (comment)>
:
> +
+To run the minesweeper example:
+
+1. Make sure you [have the prerequisites installed](https://mud.dev/quickstart#prerequisites): [Node](https://mud.dev/quickstart#prerequisites), [Foundry](https://book.getfoundry.sh/getting-started/installation), [`git`](https://git-scm.com/downloads), and [`pnpm`](https://git-scm.com/downloads).
+
+2. Clone the repository.
+
+ ```sh copy
+ git clone https://github.com/qbzzt/20240901-secret-state.git
+ ```
+
+3. Install the packages.
+
+ ```sh copy
+ cd 20240901-secret-state/
+ pnpm install
Personally encountered some node and pnpm version issues here. Looks like
user will need node 18 and pnpm 8 or 9? I had issues above this.
------------------------------
In public/content/developers/tutorials/secret-state/index.md
<#13783 (comment)>
:
> + ```sh copy
+ pnpm dev
+ ```
+
+ Note that the startup takes a long time. To see the progress, first use the down arrow to scroll to the _contracts_ tab to see the MUD contracts being deployed. When you get the message _Waiting for file changes…_, the contracts are deployed and further progress will happen in the _server_ tab. There, you wait until you get the message _Verifier address: 0x...._.
I'm not getting this personally.. I get something like this, and then the
process finishes.
> mud-template-react@ dev .> mprocs
Nothing ends up being served to localhost:3000 when I do this.
------------------------------
In public/content/developers/tutorials/secret-state/index.md
<#13783 (comment)>
:
> +
+5. Now you can browse to [the client](http://localhost:3000), click **New Game**, and start playing.
+
+### Tables {#tables}
+
+We need [several tables](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/mud.config.ts) onchain.
+
+- `Configuration`: This table is a singleton, it has no key and single record. It is used to hold game configuration information:
+ - `height`: The height of a minefield
+ - `width`: The width of a minefield
+ - `numberOfBombs`: The number of bombs in each minefield
+- `VerifierAddress`: This table is also a singleton. It is used to hold one part of the configuration, the address of the verifier contract (`verifier`). We could have put this information in the `Configuration` table, but it is set by a different component, the server, so it's easier to put it in a separate table.
+
+- `PlayerGame`: The key is the player's address. The data is:
+
+ - `gameId`: 32 byte value that is the hash of the map the player is playing on (the game identifier).
⬇️ Suggested change
- - `gameId`: 32 byte value that is the hash of the map the player is playing on (the game identifier).
+ - `gameId`: 32-byte value that is the hash of the map the player is playing on (the game identifier).
------------------------------
In public/content/developers/tutorials/secret-state/index.md
<#13783 (comment)>
:
> + - `width`: The width of a minefield
+ - `numberOfBombs`: The number of bombs in each minefield
+- `VerifierAddress`: This table is also a singleton. It is used to hold one part of the configuration, the address of the verifier contract (`verifier`). We could have put this information in the `Configuration` table, but it is set by a different component, the server, so it's easier to put it in a separate table.
+
+- `PlayerGame`: The key is the player's address. The data is:
+
+ - `gameId`: 32 byte value that is the hash of the map the player is playing on (the game identifier).
+ - `win`: a boolean that is whether the player won the game.
+ - `lose`: a boolean that is whether the player lost the game.
+ - `digNumber`: the number of successful digs in the game.
+
+- `GamePlayer`: This table holds the reverse mapping, from `gameId` to player address.
+
+- `Map`: The key is a tuple of three values:
+
+ - `gameId`: 32 byte value that is the hash of the map the player is playing on (the game identifier).
⬇️ Suggested change
- - `gameId`: 32 byte value that is the hash of the map the player is playing on (the game identifier).
+ - `gameId`: 32-byte value that is the hash of the map the player is playing on (the game identifier).
------------------------------
In public/content/developers/tutorials/secret-state/index.md
<#13783 (comment)>
:
> +
+[Zokrates](https://zokrates.github.io/) isn't the only zero-knowledge library available, but it is similar to a normal, [imperative](https://en.wikipedia.org/wiki/Imperative_programming) programming language and supports boolean variables.
+
+For your application, with different requirements, you might prefer to use [Circum](https://docs.circom.io/getting-started/installation/) or [Cairo](https://www.cairo-lang.org/tutorials/getting-started-with-cairo/).
+
+### When to compile Zokrates {#when-compile-zokrates}
+
+In this program we compile the Zokrates programs [every time the server starts](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L60-L61). This is clearly a waste of resources, but this is a tutorial, optimized for simplicity.
+
+If I were writing a production-level application, I'd check if I have a file with the compiled Zokrates programs at this minefield size, and if so use that. The same is true for deploying a verifier contract onchain.
+
+### Creating the verifier and prover keys {#key-creation}
+
+[Key creation](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L63-L69) is another pure calculation that needn't be done more than once for a given minefield size. Again, it is done only once for the sake of simplicity.
+
+Additionally, we could use [a setup ceremony](https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony). The advantage of a setup ceremony is that you need either the entropy or some intermediate result from each participant to cheat on the zero-knowlege proof. If at least one ceremony participant is honest and deletes that information, the zero-knowledge proofs are safe from certain attacks. However, there is _no mechanism_ to verify that information has been deleted from everywhere. If zero-knowledge proofs are critically important, you want to participate in the setup ceremony.
⬇️ Suggested change
-Additionally, we could use [a setup ceremony](https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony). The advantage of a setup ceremony is that you need either the entropy or some intermediate result from each participant to cheat on the zero-knowlege proof. If at least one ceremony participant is honest and deletes that information, the zero-knowledge proofs are safe from certain attacks. However, there is _no mechanism_ to verify that information has been deleted from everywhere. If zero-knowledge proofs are critically important, you want to participate in the setup ceremony.
+Additionally, we could use [a setup ceremony](https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony). The advantage of a setup ceremony is that you need either the entropy or some intermediate result from each participant to cheat on the zero-knowledge proof. If at least one ceremony participant is honest and deletes that information, the zero-knowledge proofs are safe from certain attacks. However, there is _no mechanism_ to verify that information has been deleted from everywhere. If zero-knowledge proofs are critically important, you want to participate in the setup ceremony.
------------------------------
In public/content/developers/tutorials/secret-state/index.md
<#13783 (comment)>
:
> +### The dig program {#dig-program}
+
+This is the heart of the zero-knowledge part of the application, where we produce the proofs that are used to verify dig results.
+
+```
+${hashFragment}
+
+// The number of mines in location (x,y)
+def map2mineCount(bool[${width+2}][${height+2}] map, u32 x, u32 y) -> u8 {
+ return if map[x+1][y+1] { 1 } else { 0 };
+}
+```
+
+#### Why map border {#why-map-border}
+
+Zero-knowlege proofs use [arithmetic circuits](https://medium.com/web3studio/simple-explanations-of-arithmetic-circuits-and-zero-knowledge-proofs-806e59a79785), which don't have an easy equivalent to an `if` statement. Instead, they use the equivalent of the [conditional operator](https://en.wikipedia.org/wiki/Ternary_conditional_operator). If `a` can be either zero or one, you can calculate `if a { b } else { c }` as `ab+(1-a)c`.
⬇️ Suggested change
-Zero-knowlege proofs use [arithmetic circuits](https://medium.com/web3studio/simple-explanations-of-arithmetic-circuits-and-zero-knowledge-proofs-806e59a79785), which don't have an easy equivalent to an `if` statement. Instead, they use the equivalent of the [conditional operator](https://en.wikipedia.org/wiki/Ternary_conditional_operator). If `a` can be either zero or one, you can calculate `if a { b } else { c }` as `ab+(1-a)c`.
+Zero-knowledge proofs use [arithmetic circuits](https://medium.com/web3studio/simple-explanations-of-arithmetic-circuits-and-zero-knowledge-proofs-806e59a79785), which don't have an easy equivalent to an `if` statement. Instead, they use the equivalent of the [conditional operator](https://en.wikipedia.org/wiki/Ternary_conditional_operator). If `a` can be either zero or one, you can calculate `if a { b } else { c }` as `ab+(1-a)c`.
------------------------------
In public/content/developers/tutorials/secret-state/index.md
<#13783 (comment)>
:
> + zokrates compile --input dig.zok
+ zokrates setup -e ""
+ ```
+
+4. Create the Solidity verifier on your own, and verify it is functionally identical to the one on the blockchain (the server adds a comment, but that's not important).
+
+ ```sh copy
+ zokrates export-verifier
+ diff verifier.sol ~/20240901-secret-state/packages/contracts/src/verifier.sol
+ ```
+
+## Design decisions {#design}
+
+In any sufficiently complex application there are competing design goals that require trade-offs. Let's look at some of the tradeoffs and why the current solution is preferable to other options.
+
+### Why zero-knowlege {#why-zero-knowledge}
⬇️ Suggested change
-### Why zero-knowlege {#why-zero-knowledge}
+### Why zero-knowledge {#why-zero-knowledge}
—
Reply to this email directly, view it on GitHub
<#13783 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADBCGGLWDU7CJ34PLRD4OVT2QJVIDAVCNFSM6AAAAABNS2G7L2VHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDMMRSGA3TEMBQGU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Co-authored-by: Paul Wackerow <[email protected]>
It won't hurt if it's already installed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! Thanks a lot @qbzzt, this was a great read through. Definitely a topic I'm not as well versed in, so was nice to clone and see a real example and have the stack broken down like that.
Couple small polishes/patches and one suggestion then I think we're good to pull this in!
Co-authored-by: Paul Wackerow <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks so much @qbzzt! 🔥
Congrats, your important contribution to this open-source project has earned you a GitPOAP! GitPOAP: 2025 Ethereum.org Contributor: Join the [ethereum.org Discord server](https://ethereum.org/discord) to explore more ways to contribute to the project. Depending on the tasks you complete, you may also unlock additional rewards. Visit [ethereum.org/contributing](https://ethereum.org/contributing) to learn more.Head to gitpoap.io & connect your GitHub account to mint!Keep buidling, keep learning, and let's grow the Ethereum open-source community together 🌱 Learn more about GitPOAPs here. |
Description
Onchain games are limited because they cannot keep any hidden information. After reading this tutorial, a reader will be able to combine zero-knowledge proofs and server components (see #13228) to create verifiable games with a secret state, offchain, component.
The technique to do this will be demonstrated by creating a minesweeper game.
Preview link
https://deploy-preview-13783--ethereumorg.netlify.app/en/developers/tutorials/secret-state/
Related Issue