Module 8 - Building a Tic Tac Toe Contract on Router Chain
Cloning the Repository
For Understanding how to Write a Smart Contract for Tic Tac Toe Game on Router Chain, Clone the Below Repository in your Local Machine -
This will Clone a Tic Tac Toe Game Smart Contract in the Current Directory.
File Structure
In this Module, the File Structure under src/
Directory is -
Directorysrc/
- contract.rs
- data.rs
- errors.rs
- execution.rs
- lib.rs
- msg.rs
- query.rs
- state.rs
- tests.rs
Contract.rs
Below is the Explaination of Contract.rs
file -
Imports and Configuration
This Section Imports necessary Modules and Types -
- Custom Modules for Error Handling, Execution Logic, Message Definitions, Querying, and State Management.
- CosmWasm Standard Library Types and functions.
- CW2 for Contract Versioning.
Contract Version
These Constants Define the Contract Name and Version, used for Migration Purposes.
Instantiate Function
This function is Called when the Contract is first Deployed -
- It Sets the Contract Version in Storage.
- Initializes the Games Count to 0.
- Returns a response with an “action” Attribute.
Execute Function
This Function handles all state-changing Operations -
- It uses Pattern Matching to Route Different Types of Execute Messages to their respective Handler functions.
- Supports actions like Inviting a Player, Rejecting/accepting Invitations, and making Moves.
Query Function
This Function handles read-only Operations -
- It uses Pattern Matching to Route Different Types of Query Messages.
- Supports Queries for Contract Version, Specific Game Information, and Multiple Games based on Status.
data.rs
Below is the Explaination of data.rs
file -
Imports and Configuration
These are the Import Statements -
cosmwasm_std::Addr
: This is a Type from the CosmWasm Standard Library that represents a Blockchain Address.schemars::JsonSchema
: This Trait is used to Generate JSON Schema for the Struct, which is useful for Documentation and Client-side Validation.serde::{Deserialize, Serialize}
: These Traits allow the Struct to be Serialized and Deserialized, which is necessary for Storing and Retrieving Data from the Blockchain.crate::state::Game
: This Imports theGame
Type from thestate.rs
file in the same Crate, which likely Contains the Core Game State.
Struct
This Defines a Struct called GameResponse
-
-
The
#[derive(...)]
attribute automatically Implements Several Traits for the Struct -Serialize
andDeserialize
: For Converting the Struct to and from formats like JSON.Clone
: Allows the Struct to be Duplicated.Debug
: Enables formatting of the Struct for Debugging Purposes.PartialEq
: Allows Instances of the Struct to be compared for Equality.JsonSchema
: Generates a JSON Schema for the Struct.
-
The Struct has three Fields -
game
: Of typeGame
, which likely Contains the Current State of the Game (board position, whose turn it is, etc.).host
: Of typeAddr
, representing the Blockchain Address of the Player who Created or is hosting the Game.opponent
: Also of typeAddr
, representing the Blockchain Address of the Other Player.
This GameResponse
struct is used when Querying the Contract for Information about a Specific Game. It Packages together all the Relevant Information about a Game: its Current State and the Addresses of Both Players Involved.
errors.rs
Below is the Explaination of errors.rs
file -
Imports and Configuration
cosmwasm_std::{Addr, StdError}
: Imports theAddr
Type (for blockchain addresses) andStdError
(standard errors) from CosmWasm.thiserror::Error
: A Library for easily Defining Custom Error Types.super::state::Coord
: Imports theCoord
Type from thestate.rs
file, likely representing Game Board Coordinates.
Error Enum Definition
This Defines a Custom Error Enum called ContractError
. The Derive Macros provide -
Error
: Implements thestd::error::Error
Trait.Debug
: Allows formatting of the Error for Debugging.PartialEq
: Allows Comparing Errors for Equality.
Error Variants
-
Standard Error:
Wraps Standard CosmWasm Errors.
-
Authorization Error:
Used When an Operation is attempted by an Unauthorized Address.
-
Invalid Game Start:
Prevents a Player from Starting a Game against themselves.
-
Duplicate Game:
Prevents Starting a new Game when One already exists Between the same Players.
-
Game Not Found:
Used when Trying to Interact with a non-existent Game.
-
Invalid Game:
Indicates an Issue with the Game’s State.
-
Coordinate Already Played:
Prevents Playing on an already Occupied Position.
-
Out of Turn Play:
Prevents a Player from making Multiple moves in a Row.
-
Invalid Coordinate:
Ensures that Played Coordinates are within the Valid Range (0-2 for a 3x3 board).
-
Invalid Funds:
Ensures that the Correct amount of Funds is sent with game-related Transactions.
execution.rs
This execution.rs
file Contains the Core Logic for Executing Various actions in the Tic-Tac-Toe Game Implemented as a CosmWasm Smart Contract. Let’s Break Down each function -
1. try_invite
This function handles the Invitation to Start a new Game.
Key points -
- Validates the Opponent’s Address and the Initial Coordinate.
- Prevents self-play (playing against oneself).
- Increments and Saves the Game Count.
- Creates a new Game and Saves it to Storage.
- Returns a Response with Game Details.
2. try_reject
This function allows Rejecting a Game Invitation.
Key points -
- Determines the Correct Key for the Game Based on whether the Rejector is the host or not.
- Checks if the Game exists and is in the INVITED State.
- Updates the Game Status to REJECTED.
- Refunds the Prize to the appropriate Address.
3. try_accept
This function handles accepting a Game Invitation.
Key points -
- Validates the Coordinate and Checks if the Game exists and is in the INVITED State.
- Ensures the Coordinate hasn’t been Played and the Correct funds are sent.
- Updates the Game State (doubles the prize, plays the move, finishes the round).
- Changes the Game Status to PLAYING.
4. try_play
This function handles making a Move in an Ongoing Game.
Key points -
- Validates the Coordinate and Retrieves the Game.
- Checks if the Move is Valid (coordinate not played, correct player’s turn).
- Updates the Game State with the new Move.
- Checks for a Win or Draw Condition.
- If the Game is Completed, handles Prize Distribution.
- Returns a response with the Updated Game State.
lib.rs
The lib.rs
file Serves as the Root of the Rust Crate for the Tic-Tac-Toe Game Contract. Let’s break it Down line by line -
Imports and Configuration
This Declares a Public Module named contract
. The pub
Keyword makes this module accessible to other Crates that might use this one. This Module likely Contains the Main Contract Logic, including Entry Points for Instantiation, Execution, and Querying.
These lines Declare several Private Modules. They’re not prefixed with pub
, so they’re only accessible within this Crate. Each module likely Corresponds to a Separate file -
data
: Probably Contains Data Structures used throughout the Contract.errors
: Defines Custom Error Types for the Contract.execution
: Likely Contains the Logic for Executing various Contract Actions.msg
: Probably Defines Message Types for Contract Interactions.query
: Likely Contains Logic for Querying Contract State.state
: Probably Defines the Contract’s State and Storage Logic.
This Line re-exports the Deserialize
and Serialize
Traits from the serde
Crate. This makes these Traits available to Users of this Crate without them needing to explicitly Import serde
. These Traits are Crucial for Serialization and Deserialization in CosmWasm Contracts.
This Declares a tests
Module that’s only Compiled when Running Tests (due to the #[cfg(test)]
attribute). This is where Unit Tests for the Contract would be located.
msg.rs
This msg.rs
file Defines the Message Structures used for Interacting with the Tic-Tac-Toe Game Contract. These Structures are Crucial for Defining how Users and other Contracts can Interact with this Smart Contract.
Imports and Common Traits
JsonSchema
: For Generating JSON Schema for the Structs.Deserialize
,Serialize
: For Converting between Rust Types and JSON.Coord
,Status
: Custom Types from the Contract’sstate
Module.
All Structs and Enums are Derived with Serialize
, Deserialize
, Clone
, Debug
, PartialEq
, and JsonSchema
traits, which are Standard for CosmWasm Message Types.
InstantiateMsg
This Empty Struct is used when Instantiating the Contract. In this case, no Initial Configuration is needed.
ExecuteMsg
This Enum Defines the possible Execute Messages -
Invite
: Start a new Game, specifying the first Move and Opponent.Reject
: Reject a Game Invitation.Accept
: Accept a Game Invitation and make the first Move.Play
: Make a Move in an Ongoing Game.
The #[serde(rename_all = "snake_case")]
attribute Ensures that the Enum Variants are Serialized in snake_case, which is the Convention in JSON.
QueryMsg
This enum defines the possible query messages -
GetContractVersion
: Retrieve the Contract’s Version Information.Game
: Query a Specific Game by its Key and ID.Games
: Query Multiple Games, Optionally filtered by Status.
QueryKey
This Struct is used to Specify the Key for Querying a Specific Game, Consisting of the host and Opponent addresses.
query.rs
The query.rs
file Defines two Main Query functions for the Tic-Tac-Toe Game Contract: query_game
and query_games
. These functions allow Users or other Contracts to retrieve Information about Specific Games or Sets of Games.
Imports and Configuration
GameResponse
: A Struct representing the response format for Game Queries.QueryKey
: A Struct used to Specify the Key for Querying a Specific Game.Status
,GAMES
: From the Contract’s State Module, likely an Enum for Game Status and a Storage Map for Games.Deps
,Order
,StdResult
: CosmWasm Standard Types for Dependency Injection, Ordering, and Results.
query_game Function
This function Queries a Specific Game -
- It Validates the Host and Opponent Addresses from the
QueryKey
. - It attempts to Load the Game from Storage using
GAMES.may_load()
. - If the Game is found, it Constructs a
GameResponse
with the Game Data and Player addresses. - It returns a Vector Containing either one
GameResponse
(if the game is found) or an Empty Vector (if not found).
query_games Function
This function Queries Multiple Games, Optionally filtered by Status -
- It uses
GAMES.range()
to Iterate over all Games in Storage. - For each Game, it Constructs a
GameResponse
with the Game Data and Player addresses. - If a Status filter is Provided, it filters the Results to include only Games matching that Status.
- It returns a Vector of all matching
GameResponse
Objects.
Error Handling
Both functions return StdResult<Vec<GameResponse>>
, allowing for Propagation of any Errors that might occur During address Validation or Storage access.
state.rs
The state.rs
file Defines the Core Data Structures and Storage Mechanisms for the Tic-Tac-Toe Game Contract. It includes Game Logic, State Management, and persistent Storage Definitions.
Imports and Setup
fmt
: For Implementing Custom formatting Traits.Addr
,Coin
,Uint128
: CosmWasm Types for addresses, Coins, and Large Integers.Item
,Map
: CosmWasm Storage Primitives.JsonSchema
,Deserialize
,Serialize
: For JSON Schema Generation and Serialization.
Game Struct
This Struct represents the State of a single Tic-Tac-Toe Game -
board
: A 3x3 Grid represented as nested Vectors.host_symbol
: The Symbol (X or O) of the Game Creator.player_round
: Indicates whose turn it is.prize
: The Reward for the Winner.status
: Current Game State (INVITED, PLAYING, COMPLETED, REJECTED).winner
: The Winner of the Game, if any.
Supporting Types
PlayerSymbol
: Represents the two Possible Player Markers.Status
: Represents the four possible Game States.Coord
: Represents a position on the Game Board.
Game Logic Implementation
The Game
struct Implements Several Methods -
Persistent Storage
GAMES_COUNT
: Keeps Track of the Total number of Games.GAMES
: Stores Individual Game States, keyed by Both players’ Addresses and a Game ID.
This State Definition provides a Robust Foundation for the Tic-Tac-Toe Game, handling Game Mechanics, State Transitions, and Blockchain Integration efficiently. It’s Designed to be used in Conjunction with other Contract Components like Message handling (msg.rs
) and Querying (query.rs
) to Create a full-featured Blockchain-based Game.
tests.rs
This file Basically Comprises of all the Tests Scripts used for Testing of the Smart Contract.