This project showcases a Plinko game implementation on the Sui blockchain. You can explore the game mechanics and interact with the smart contracts in our development environment.
You can test the Plinko game on testnet. Log in with your preferred OAuth provider, verify that you have at least 2 Sui in your wallet (1 for the minimum bet and 1 Sui, a portion of which will be used for paying gas).
Plinko, inspired by the popular game show, is a game of chance where balls are dropped from the top of a pegged board, and the outcome is determined by the path they take. Our Sui blockchain implementation offers a unique experience by integrating cryptographic techniques to ensure fairness and transparency.
The Plinko game on Sui Blockchain incorporates advanced cryptographic techniques to ensure fairness and transparency. Players drop balls into a pegged board, where they randomly fall into slots representing different multipliers.
- Starting a Game: Players initiate a game by specifying the number of balls and staking a certain amount of SUI tokens. Each ball's path through the pegged board determines the final multiplier affecting the player's stake.
- Finishing a Game: Upon completion, the game calculates the total payout based on the paths of all balls and multipliers they hit. The smart contract then transfers the winnings back to the player's account.
- Purpose: Ensures that the path each ball takes is provably random and tamper-proof.
- Implementation: Utilizes the BLS signature scheme. The game's outcome is based on the hash of a unique input, which includes the BLS signature, an incrementing counter, and the number of balls the user has selected.
- Mechanism: The game verifies the authenticity and integrity of the VRF input using the house's public key. This step ensures that the randomness source is legitimate and unaltered.
- Process: The
bls12381_min_pk_verify
function checks the BLS signature against the house's public key and the VRF input. If the verification fails, the game aborts withEInvalidBlsSig
to prevent manipulation.
The trace path of each ball is determined by extending the beacon generated from the BLS signature. The extended beacon provides a sufficient random byte sequence to calculate the path for each ball.
- Extended Beacon Generation: For each ball, the game generates a unique hash input by concatenating the BLS signature with a counter. The hash of this input is added to the extended beacon, ensuring a large enough sequence for all balls.
- Path Calculation: The game iterates through the extended beacon, using 12 bytes for each ball to determine its path based on the pegs it encounters. Each byte influences the ball's direction, simulating the physical behavior of a Plinko board.
- Dynamic Multipliers: The game uses a predefined array of multipliers corresponding to the slots at the bottom of the Plinko board.
- Outcome Determination: The final position of each ball, derived from its trace path, maps to a specific multiplier. The total payout is the cumulative result of applying these multipliers to the player's stake.
- Immutable Smart Contracts: The game logic is deployed as immutable smart contracts on the Sui Blockchain, ensuring transparency and tamper-resistance.
- Public Verification: All transactions, including game starts, outcomes, and payouts, are recorded on the blockchain. This allows anyone to verify the fairness and randomness of each game.
- The
counter_nft
module creates a unique Counter NFT for each game round. - The
house_data
module sets up the game's parameters and manages the house's treasury. - The
plinko
module handles the gameplay, including starting a game, calculating outcomes, and distributing rewards.
The project is structured into three main directories:
app/
: Contains the front-end code of the Plinko game.api/
: Houses the backend server code that interacts with the Sui blockchain.plinko/
: Includes the smart contracts written in Sui Move for the Plinko game.
To get started with the Plinko game, you need:
- A Sui address with SUI coins.
- Sui Client CLI configured to connect to the Sui Testnet.
- A Sui-compatible wallet (like Sui Wallet).
- npm and Node.js installed on your machine.
Follow these steps to set up and interact locally with the Plinko game:
- Switch to the desired environment with
sui client switch --env testnet|devnet
. - Ensure your active Sui address has sufficient SUI coins.
- Export your admin address by running:
export PLINKO_HOUSE_ADDRESS=your_house_address
. - Export your admin Private Key by running:
export PLINKO_HOUSE_PRIVATE_KEY=your_house_secret_key_here
. - Move to the
setup/
directory and follow the detailed instructions from the README file. - Deploy the contract and setup the environment with
./publish testnet | devnet
.
The publish
script deploys the contract and initializes the game environment. For more details, refer to the publish
README.
- Move to the
api/
directory and runnpm install
. - Start the server locally with
npm run dev
. It will run atlocalhost:8080
. - You can follow the api/README.md file for more information.
- Navigate to the
app/
directory. - Run
npm install
, followed bynpm run dev
for local testing. - Access the UI at
localhost:3000
and enjoy the Plinko game. - You can follow the app/README.md file for more information.
Our Plinko game leverages the Sui blockchain's capabilities to ensure a fair and transparent gaming experience. All transactions and outcomes are verifiable on the chain, upholding the integrity of the game.
This project is powered by Mysten Labs and the Sui blockchain technology.
The sequence diagram below illustrates the interaction flow from the player initiating a game to displaying the game result.
sequenceDiagram
participant Player as Player
participant UI as Next.js Application
participant API as Backend API
participant Blockchain as Sui Blockchain
Note over Player, Blockchain: Plinko Game Interaction Flow
Player->>+UI: Places bet, selects number of balls, presses play
UI->>Player: Displays game as pending, awaiting outcome
UI->>+Blockchain: Sends bet and number of balls
UI->>+Blockchain: Calls counter_nft::mint to produce vrf_input, calls plinko::start_game
Note over Blockchain: Checks stakes, balances, creates and increments the counter, emits 'NewGame' event
Blockchain-->>-UI: Returns gameId, vrfInput
UI->>+API: POST /game/plinko/end with { gameId, vrfInput, numberOfBalls }
Note over UI: Reads from the 'NewGame' event gameId, vrfInput
Note over API: Signs vrfInput with house's private key
API->>+Blockchain: Calls plinko::finish_game with signed vrfInput
Note over Blockchain: Verifies signature, calculates outcome (payments, balls' trace paths), emits Outcome event
Blockchain-->>-API: Returns game outcome event (trace paths, winnings)
API-->>-UI: Sends game outcome (trace paths, winnings)
UI-->>-Player: Displays game result, balls' descend, and winnings