Mina Navigators: L1 Lottery

ZkNoid
5 min readJul 26, 2024

--

Proposal overview

In June, the long-awaited Berkeley update took place for the Mina ecosystem, and our team was also eager to bring our product to the Mainnet.

Mina community is interested in playing games on the Mina blockchain. The Lottery game would be the first gaming zkApp ready for the real funds. We were to launch such game considering considering that the block production on L1 is slow (one block once in 3 minutes). In this game players try their luck in a fair lottery getting used to ZK gaming experience.

During an active round that takes 480 blocks or approximately 24 hours, user can buy any number of lottery tickets to participate in. Each ticket costs 1 Mina + commission and contains 6 numbers from 1 to 9. At the end of the round, 6 numbers are generated using VRF. Depending on how many numbers were guessed, tickets are awarded with points.

Our main goal was to develop a user friendly ZK gaming experience on Mina, so we had a plan and we stuck to it:

  1. Developing smart contract, witch supports ticket purchase, winning number combination and rewards distribution. All this actions should be secured with ZK proofs.
  2. Developing backend part. To improve user experience we should implement some computation and data aggregation on backend. It will not reduce decentralisation, because all this actions can be done by anyone using public data.
  3. Research and creating friendly design for users, that takes into account ZKapp features and make them user friendly.
  4. Connecting contracts, backend and frontend parts in one working system

In addition our team wanted to bring users the smoothly experience, so we needed to to optimize all processes to reduce loadings time and proof-generating time. Let’s dive deep into lottery game development process!

Lottery rules

This game is based on users luck. Lottery round lasts 24 hours, user buys ticket and chooses 6 numbers on it, this ticket is added to his wallet. At the end of the round, a random 6-digit win number is generated and user can claim his reward if he guessed the numbers or a part of them. The percentage of winnings depends on the number of guessed numbers in the ticket.

The full rules:

  1. Round Duration: each round lasts approximately 24 hours
  2. Ticket Purchase:
    a) Each ticket costs 1 $MINA
    b) Ticket consist of 6 numbers (1–9) and quantity
    c) Duplicated tickets are allowed
  3. Platform Fees: A 3% fee is deducted from each ticket purchase
  4. Winning Ticket reveal: winning ticket revealed within 2 days after round ends
  5. Claiming Rewards: each ticket earns points( 0, 90, 324, 2187, 26244, 590490, or 31886460 for 0, 1, 2, 3, 4, 5, or 6 correct numbers). The reward is a share of the total bank based on points, order of numbers matters
  6. Refunds: If the winning ticket is not revealed within 2 days, you can get a refund for your ticket

Development

Contracts

We have implemented contract for Lottery, that have following features:

  1. Uses actions & reducers to achieve higher throughput
  2. Distribute rewards according to amount of guessed numbers. All round bank is distributed along all the users
  3. Bank distribution is secured with DistibutionProof, that calculated scores of all tickets and can be check by anyone
  4. Covered with tests
  5. Have a StateManager for easy interaction with contract
  6. Do not have any private offchain data, so anyone can run it

Backend

  1. Implemented lottery workers plus backend using Nest Js
  2. Implemented services for:
    a) Archive node events sync with mongodb supporting orphaned block events dropping
    b) State manager storing and feeding with events
    c) Distribution proof calculation
    d) Lottery round results producing
    e) Providing witnesses generation api for the claim transaction using global state manager
  3. Implemented trpc backend connected with mongodb
  4. Integrated trpc backend into frontend, which enabled
    a) Round infos fetching without loading all the lottery events
    b) Claim transaction witnesses calculation without loading all the lottery events
    c) Reduced the probability of state manager sync issues e.g. in case of uncle blocks
    d) Using already calculated distribution proof

Design

The main target in the development of design have been to create “one page” application, which includes huge lottery functionality but stay convenient and friendly for users. Design must include system for buying tickets, displaying tickets tickets, claiming rewards and showing the previous and current rounds stats such as winning number, funds of round, tickets in round and timer to check round state.

We we took into account all user winnings and their movings inside application and provided compact but functional design. In the picture below you can see the current round page with already bought tickets, opportunity to buy more and all information about curren tround and previous rounds.

Easy navigation between rounds was developed, highlighting winning numbers on your tickets, a fast-buy button in the header with all information about the round.

Frontend

The frontend team implemented all the provided designs and added animation to the tickets, buttons, and sliders to increase the interactivity of the design. Then, we implemented the initial frontend for the lottery with transactions proving and off-chain state fetching.

The proof-generating process and other backend processes, such as data sync with mongodb, could take some time, so we integrated a small toasts-notifications at the bottom of the screen to keep users updated on what processes were happening inside the application.

We moved on-chain data owning from service worker to react for faster loading and optimized contracts cache size.

Additional features

Additionally to the basic functionality, we wanted to expand the possibilities inside the game.

Now we improving our lottery application with two new features:

Tickets storage: this page will be collected all user tickets from all rounds and you can see your prizes and claim your rewards on one page without depends on number of round. Beyond that, you can filter your tickets by a wide range of parameters.

Access codes: this feature providing opportunity to generate one or more gift access codes. This will allow to presented free tickets to your friends or, for example, to hold events with the distribution of tickets for the users.

Website | Docs | Twitter | Discord | Telegram | Medium

--

--

ZkNoid

Platform for games with provable game process based on Mina protocol and o1js. Docs – docs.zknoid.io. Github – github.com/ZkNoid. Twitter – https://x.com/ZkNoid