Sitemap
Stackademic

Stackademic is a learning hub for programmers, devs, coders, and engineers. Our goal is to democratize free coding education for the world.

How to Build a Coin Flip Game Smart Contract on Sui Blockchain Using Move

4 min readDec 27, 2024

--

Press enter or click to view image in full size

This tutorial explains how to create a coin flip smart contract using Move on the Sui blockchain. The contract allows players to bet on the outcome of a virtual coin flip, and it emits events to record the results.

Introduction

The coin flip game is a simple betting game where players predict the outcome of a coin toss. This tutorial demonstrates how to:

  • Implement a smart contract module for the coin flip game.
  • Use randomness in Move for generating outcomes.
  • Emit events to track results.

Prerequisites

Before diving into the coding, make sure you have the following set up:

  • Sui CLI: Required for deploying contracts. Install Sui CLI.
  • Code Editor: A good editor like VS Code or IntelliJ with the Move plugin.

1. Set Up a Sui Move Project

Run the following command to scaffold a new Sui Move project:

sui move new coinflip

This will create a directory named coinflip with the following structure:

coinflip/
├── Move.lock
├── Move.toml
├── sources/
│ └── coinflip.move
└── tests/
└── coinflip_tests.move

Navigate to the Project Directory

cd coinflip

Replace the contents of sources/coinflip.move with the code for your module (explained in the following steps).

2. Module Definition

module coinflip::coinflip;

This defines the CoinFlip module under the coinflip package. It encapsulates the logic and structure for the coin flip game.

3. Imports SUI event and random

use sui::{
event,
random::Random
};
  • event: Allows the contract to emit events, which are useful for logging and tracking on-chain actions.
  • random::Random: Provides random number generation capabilities, essential for implementing the coin flip logic.

4. Struct Definition: Flip

public struct Flip has copy, drop, store {
player: address,
player_won: bool,
bet: bool,
}

The Flip struct represents the outcome of a coin flip. It includes:

  • player: The address of the player who flipped the coin.
  • player_won: A boolean indicating whether the player's prediction matched the coin flip result.
  • bet: The player's prediction (true for heads, false for tails).

Access Modifiers:

  • public: The struct is accessible outside the module.
  • has copy, drop, store: Specifies the struct's storage and memory capabilities:
  • copy: Instances of Flip can be copied.
  • drop: Instances can be discarded.
  • store: Instances can be stored in the Sui blockchain's storage.

5. Private Function: flip_impl

This function implements the core logic for the coin flip.

fun flip_impl(
random: &Random,
bet: bool,
ctx: &mut TxContext
): bool {
let mut gen = random.new_generator(ctx);

let result = gen.generate_bool();

result == bet
}

Inputs:

  • random: A reference to the Sui Random object, used to generate random values.
  • bet: The player's prediction (true or false).
  • ctx: The transaction context, required for creating or managing on-chain resources.

Logic:

  • Creates a random generator using the random.new_generator(ctx) method.
  • Generates a random boolean value (true or false).
  • Compares the generated value (result) with the player's bet and returns whether they match.

Output:

  • Returns true if the player won (prediction matched the result).
  • Returns false otherwise.

6. Entry Function: flip

entry fun flip(random: &Random, bet: bool, ctx: &mut TxContext) {
let player_won = flip_impl(random, bet, ctx);
let player = ctx.sender();

event::emit(Flip {
player,
player_won,
bet,
});
}

This is the public entry point for flipping the coin.

Get Ryan Adhitama Putra’s stories in your inbox

Join Medium for free to get updates from this writer.

Inputs:

  • random: A reference to the Sui Random object.
  • bet: The player's prediction for the coin flip.
  • ctx: The transaction context.

Logic:

  1. Calls flip_impl to determine if the player won.
  2. Retrieves the address of the player using ctx.sender().
  3. Emits a Flip event with the player's address, whether they won, and their bet.

Event Emission:

event::emit(Flip {
player,
player_won,
bet,
});
  • The Flip event logs the result of the coin flip to the blockchain.

7. Full Source Code

module coinflip::coinflip;

use sui::{
event,
random::Random
};

public struct Flip has copy, drop, store {
player: address,
player_won: bool,
bet: bool,
}

// === Private Functions ===
fun flip_impl(
random: &Random,
bet: bool,
ctx: &mut TxContext
): bool {
let mut gen = random.new_generator(ctx);

let result = gen.generate_bool();

result == bet
}

// === Public-Mutative Functions ===
entry fun flip(random: &Random, bet: bool, ctx: &mut TxContext) {
let (player_won) = flip_impl(random, bet, ctx);
let player = ctx.sender();

event::emit(Flip {
player,
player_won,
bet
});
}

8. Deploy the Module

Follow these steps to deploy your coinflip module:

Compile the Contract
Navigate to the project directory and run:

sui move build

Publish the Contract
Use the Sui CLI to publish the module:

sui client publish --gas-budget 100000000

Deployed Package

9. Interact Using Sui Client

Use the following command to test the flip function:

sui client call \
--package <PackageId> \
--module coinflip \
--function flip \
--args <Random_ObjectId> true \
--gas-budget 10000000
  • Replace <PackageId> with the ID of your deployed coinflip module.
  • Replace <Random_ObjectId> with the ID of the Random object.
  • The last argument (true) is the player's bet (true for heads, false for tails).

Example

sui client call --package 0xdf9fe77476b037e4d18850983811af3585d111e13758d36ed56fa6bca50eee53 \
--module coinflip \
--function flip \
--args "0x0000000000000000000000000000000000000000000000000000000000000008" true \
--gas-budget 10000000

Conclusion

You have successfully created a coin flip smart contract on the Sui blockchain. This contract uses randomness for fair results and emits events to log outcomes.

Thank you for being a part of the community

Before you go:

--

Ryan Adhitama Putra
Ryan Adhitama Putra

Written by Ryan Adhitama Putra

Software Engineer ; Tech Enthusiast ;

Stackademic
Stackademic

Published in Stackademic

Stackademic is a learning hub for programmers, devs, coders, and engineers. Our goal is to democratize free coding education for the world.