Build a ZK Game
In this tutorial, you will build a game where users can prove and verify their high scores onchain. You will also learn how to integrate ZKsync SSO.
What you'll learn:
- How to generate and verify ZK proofs onchain
- A way to use ZK proofs with a game
- How to integrate ZKsync SSO
Tools:
- - sso
- - sp1
- - wagmi
- - zksync-ethers
- - hardhat
Prerequisites
- You must have access to SP1's prover network. Follow these instructions to gain access to the network.
- This tutorial uses TypeScript, Rust, and Solidity. You should have some experience with at least two of these languages.
- You must have Node.js version
20
installed. - You must have the
nightly
Rust toolchain installed. - You will need Docker Desktop installed to run a local node.
What You Will Build
In this tutorial you will build a game that:
- Lets users verify their high scores onchain using ZK proofs.
- Integrates ZKsync SSO and a paymaster for seamless UX.
Why use ZK?
If you have ever tried to build a game onchain, you know that there are some unique limitations. For example, if you put every player move onchain, the game quickly becomes slow and expensive. But without every move onchain, how can you verify the player's achievements in a permissionless way?
What if you could somehow let anyone prove their own final score onchain, without giving away how they achieved it? What if you could give players the option of skipping any onchain activity when they didn't get the score they wanted?
One way to accomplish this is by using ZK proofs.
Introduction to ZK proofs
If you are new to ZK proofs, here is a very brief summary of what you need to know:
- ZK is an abbreviation for Zero Knowledge.
- ZK allows you to prove some computation is correct, without needing to reveal all of the input data.
- There are two steps to using ZK: 1) creating proofs, and 2) verifying those proofs.
- A proof and its public outputs can be verified onchain using a verifier contract.
- An important property of ZK is that verifying the proofs is very cheap. If you use a ZK proof for a large computation, the blockchain only needs to do a very small verification. This is very helpful for saving costs.
How it will work
We will use a re-creation of a popular game known as "Breakout" or "Brickles". The game will record the player's movements on the client.
When the player decides to save their high score onchain, the client will send the recorded actions, final score, and time to a backend service to generate a proof.
On the backend, the game will be re-run using those recorded actions inside an SP1 program. In the game contract, we will make sure that this exact program is being run using a program verification key. With this, we are able to create a proof that the recorded actions indeed produce the same score and time that the player claims.
One condition of this method is that the game must be deterministic. This means that for a given player's inputs, it will always result in the same score. The game logic is written entirely in Rust, ensuring that the exact same code runs on both the client and the backend.
Finally, once the API returns the proof data, the player can verify the score onchain using their SSO account. The transaction will be sponsored with a paymaster contract so the player doesn't need funds to play.
In the next section, we will get started with the onchain contracts.