Ronin: Make a game's smart contract
TLDR:
- Ronin is an EVM-compatible chain optimized for large-scale Web3 gaming, offering streamlined gameplay and robust security.
- This tutorial walks you through deploying a Ronin node on the Saigon Testnet and creating a Hardhat-based smart contract for a simple blockchain game.
- The contract accepts deposits, verifies if players can participate, and pays out winners while retaining funds when players lose—illustrating a basic on-chain gaming model.
- You’ll learn to configure Hardhat, manage environment variables, and deploy your contract to Ronin for full transparency and fair gameplay.
Introduction to Ronin
Ronin, an Ethereum Virtual Machine (EVM) compatible blockchain, is purpose-built to serve the unique needs of the gaming industry. Developed by Sky Mavis, the creators of Axie Infinity, Ronin stands out for its ability to support large-scale online games, specifically in the realm of Web3 gaming.
Key technical features of Ronin
-
Optimized for gaming: Ronin is designed to streamline the gaming experience by removing the complexities commonly found in other blockchains. This results in a platform that is efficient, with minimal spam and optimized uptime for games.
-
Security enhancements: in response to security challenges faced in the past, Ronin has undergone extensive security overhauls. These include rigorous internal security protocols, comprehensive code reviews, and architecture audits to ensure robust security measures are in place.
Consensus mechanisms in Ronin
-
Proof-of-authority (PoA) — Ronin initially utilized the PoA consensus mechanism. In this system, a select group of validators, trusted for their expertise and reputation, were responsible for maintaining the network. This approach facilitated faster transaction speeds and lower fees due to its energy-efficient design.
-
Transition to delegated-proof-of-stake (DPoS) — Ronin integrated the DPoS consensus mechanism to advance decentralization. This allowed broader participation in the network’s maintenance, where anyone holding enough RON tokens could become a validator. While retaining the benefits of PoA, such as efficiency and low costs, this shift markedly improved the blockchain’s decentralization.
Check out the Ronin docs to learn more.
Since Ronin is designed to develop games, today, we’ll make a smart contract that can handle for games.
In this tutorial, you will:
- Deploy a Ronin node on the Saigon Testnet.
- Create the game smart contract with Hardhat.
- Deploy the smart contract with Hardhat
Prerequisites
- Chainstack account to deploy a Ronin node.
- node.js as the JavaScript framework.
- Hardhat to create, deploy, and interact with contracts.
Overview
This tutorial guides you through the process of developing a smart contract for a blockchain-based game specifically tailored for deployment on the Ronin Saigon Testnet. We aim to develop a versatile and robust smart contract capable of managing the core game logic on the blockchain.
The game itself is designed to be played on the client side, typically within a web browser. Players will have the ability to connect their Ronin wallet and deposit a specified fee to begin gameplay. The smart contract plays a pivotal role in the gaming experience: it securely handles the deposit and, depending on the game’s outcome, executes the payout.
To get from zero to a working game, do the following:
With Chainstack, create a public chain project.
With Chainstack, join the Ronin Saigon Testnet.
With Chainstack, access your Ronin node endpoint.
With Hardhat, create and set up the project.
Step-by-step
Create a public chain project
See Create a project.
Join the Ronin Saigon testnet
Get your Ronin node endpoint
See View node access and credentials.
Fund your wallet
Before diving into the game project, make sure to top up your wallet with testnet RON.
- Install the Ronin wallet.
- Use the Ronin faucet.
Install Hardhat
See Installing Hardhat.
Install dotenv
Install the dotenv
package to securely manage environment variables.
Create a Hardhat project
Create a new directory for your project, then run the following from a terminal:
This will launch the Hardhat CLI, prompting you to choose a starter project. For this project, answer yes to the following:
Create a JavaScript project
Do you want to install this sample project's dependencies with npm (hardhat @nomicfoundation/hardhat-toolbox)?
Edit the Hardhat configuration file
You will find a file named hardhat.config.js
in the root directory. This file configures various settings for your Hardhat projects, such as the network you want to deploy your contracts on, the compilers you want to use, and the plugins you want to enable.
Delete the default code in the file and replace it with the following:
Let’s break down what each part of the file does:
require("@nomicfoundation/hardhat-toolbox");
imports the Hardhat Toolbox plugin, which provides several useful tools and utilities for Hardhat projects.require("dotenv").config();
loads environment variables from a.env
file using thedotenv
package.module.exports = { ... }
exports a JavaScript object containing the configuration for the Hardhat project.solidity: "0.8.23",
sets the Solidity compiler version to 0.8.23.networks: { ... }
defines the network configurations for the Hardhat project. In this case, it defines a network calledsaigon
that connects to the Ronin Saigon blockchain network.saigon: { ... }
defines the configuration for thesaigon
network.url: RONIN_SAIGON_CHAINSTACK,
sets the URL for the Saigon network using theRONIN_SAIGON_CHAINSTACK
environment variable.accounts: [PRIVATE_KEY],
sets the accounts for thesaigon
network using thePRIVATE_KEY
environment variable. This will allow the Hardhat project to deploy contracts and interact with the Saigon network using the specified private key.
Create the game-handling smart contract
In the root directory, you will find a directory named contracts
with a sample contract in it. Rename this contract to Game.sol
and replace its code with the following:
Default logic
Keep in mind that this smart contract is a proof of concept and it should not be used in production as is. A security audit is higly recomended.
Understanding the smart contract
This smart contract, designed for a blockchain-based game, operates on a simple yet effective mechanism. It allows players to deposit RON (or the native currency of the chain you are using) within a specified range—a minimum of 1 ether and a maximum of 2 ethers—to participate in the game. This range ensures fair play and manages the contract’s ability to pay winnings. The contract tracks these deposits against each player’s address, maintaining a balance reflecting their current game stake.
Let’s break down each element and function of the smart contract.
Contract overview
- Contract name —
Game
- Purpose — this contract allows players to deposit ETH to play a game, and it manages the game results and payouts.
Constants
-
MINIMUM_DEPOSIT
- Type —
uint256
(unsigned integer) - Purpose — specifies the minimum amount of ether a player must deposit to play the game.
- Value — 1 ether
- Type —
-
MAXIMUM_DEPOSIT
- Type —
uint256
- Purpose — indicates the maximum amount of ether a player can deposit.
- Value — 2 ethers
- Type —
State variables
-
deposits
- Type —
mapping(address => uint256)
- Purpose — keeps track of the amount of ether each player (address) has deposited.
- Type —
-
owner
- Type —
address
- Purpose — stores the address of the contract owner, who has special privileges (like executing the
gameResult
andwithdraw
functions).
- Type —
Constructor
- Functionality — sets the deployer of the contract as the
owner
.
Modifiers
- onlyOwner
- Purpose — restricts the execution of certain functions to only the contract owner.
Functions
-
deposit
- Access — public
- Payment Type — payable (can receive ether)
- Purpose — allows players to deposit ETH within the allowed range (1 to 2 ethers). It also ensures the contract has enough funds to cover potential winnings.
- Logic — updates the
deposits
mapping with the player’s deposit amount.
-
canPlay
- Access — public
- Purpose — checks if a user has deposited enough ETH to play the game.
- Parameters —
user
(address of the player) - Returns —
bool
(True
if the player has enough deposit,False
otherwise)
-
gameResult
-
Access — public, but restricted to
onlyOwner
-
Purpose — processes the outcome of the game. It either pays out double the deposit to the player if they win or retains the deposit in the contract if they lose.
-
Parameters:
player
— address of the playeruserWon
— boolean indicating whether the player won or not
-
Logic — if the player wins, it transfers double the deposit amount to them and resets their deposit to zero. If the player loses, just resets their deposit.
-
-
withdraw
- Access — public, but restricted to
onlyOwner
- Purpose — allows the owner to withdraw all ETH stored in the contract.
- Logic — transfers the entire contract balance to the owner’s address.
- Access — public, but restricted to
TL;DR
- Players can participate in the game by depositing a certain amount of ether (between 1 and 2 ethers).
- The contract ensures fairness and readiness for payouts before accepting deposits.
- After the game ends, the result is communicated to the contract. Winners receive double their stake, while the stakes of those who lose remain with the contract.
- Only the contract owner can process game results and withdraw funds from the contract, ensuring controlled and secure operations.
Environment variables
In the root directory of the Hardat project, create a .env
file for your endpoint and private keys:
Create the deploying script
In the scripts
directory inside the root of your project, you will find a file named deploy.js
. Replace its content with the following:
This code is a script that deploys a Game
smart contract.
Here’s a breakdown of what each part of the script does:
-
Import Hardhat runtime environment (HRE):
This line imports the Hardhat runtime environment, which provides various utilities for working with Ethereum, such as deploying contracts.
-
Main function:
The
main
function is an asynchronous function where the main logic of the script is executed. -
Starting deployment process:
This line prints a message to the console indicating that the deployment process is starting.
-
Deploying the contract:
This line uses Hardhat’s
ethers
plugin to deploy a contract namedGame
. Theawait
keyword is used becausedeployContract
is an asynchronous operation. -
Waiting for deployment completion:
This line waits for the contract deployment to be completed. It’s important to wait for the deployment to finish before proceeding.
-
Logging the deployed contract address:
After the contract is successfully deployed, this line logs the address of the deployed contract to the console.
-
Removing the
0x
prefix from the address:This line removes the
0x
prefix from the Ethereum address using thesubstring
method. As the Ronin explorer uses this format:https://saigon-app.roninchain.com/address/ronin:49a1EA88e5F81850DE30Dc038c1d08028ecFc9b5
. -
Providing the contract address on Ronin explorer:
This line constructs a URL to view the contract on the Ronin blockchain explorer and logs it to the console. It appends the modified address to the explorer’s URL.
-
Error handling:
This part of the script ensures that if any errors occur during the execution of the
main
function, they are caught and printed to the console, and the script exits with an error code.
Deploy the smart contract
To deploy the Game
contract, run the following command in the terminal:
This will deploy the contract on Ronin Saigon Testnet displaying something similar to the following:
You can now find the contract on the Saigon Explorer. You can also find the transactions from the Ronin wallet.
Next steps
Now you have a working smart contract deployed, the next step will be to build a front end with your game and wallet interaction.
Conclusion
In this comprehensive tutorial, we journeyed through the exciting world of blockchain-based game development on the Ronin blockchain, an EVM-compatible platform optimized for gaming. From setting up a node on the Ronin Saigon testnet to deploying a game-centric smart contract using Hardhat, we’ve laid down a robust foundation for blockchain game developers.
The key takeaway from this tutorial is the seamless integration of blockchain technology into gaming. By deploying a smart contract on Ronin, we have created a system that enhances the gaming experience and ensures secure and fair gameplay. The ability to handle in-game financial transactions directly on the blockchain, including player deposits and payouts, showcases the power and versatility of smart contracts in gaming environments.