5. Deployment TugWar Game ke Monad Testnet
Setelah mengembangkan dan testing TugWar Game smart contract, sekarang saatnya untuk men-deploy ke Monad Testnet. Pada bagian ini, kita akan membuat satu script deployment yang sederhana namun lengkap untuk deploy dan verifikasi contract.
Daftar Isiā
1. Script Deployment Sederhanaā
Membuat Script Deploy dan Verifyā
Buat file scripts/deploy.ts
:
import { ethers } from "hardhat";
import { TugWarContract } from "../typechain-types";
async function main() {
console.log("š® TugWar Game Deployment to Monad Testnet");
console.log("=" .repeat(50));
// Get deployer account
const [deployer] = await ethers.getSigners();
const network = await ethers.provider.getNetwork();
console.log("\nš Deployment Info:");
console.log(" Deployer:", deployer.address);
console.log(" Network:", network.name);
console.log(" Chain ID:", network.chainId.toString());
// Check balance
const balance = await ethers.provider.getBalance(deployer.address);
console.log(" Balance:", ethers.formatEther(balance), "MON");
if (balance < ethers.parseEther("0.1")) {
console.error("ā Insufficient balance for deployment");
console.error(" Required: 0.1 MON minimum");
process.exit(1);
}
console.log("ā
Pre-deployment checks passed");
// Deploy TugWar Contract
console.log("\nš Deploying TugWar Contract...");
const TugWarFactory = await ethers.getContractFactory("TugWarContract");
// Estimate gas
const gasEstimate = await (await TugWarFactory.getDeployTransaction(deployer.address)).gasLimit;
const gasPrice = await ethers.provider.getFeeData();
console.log("ā½ Gas Info:");
console.log(" Estimated gas:", gasEstimate?.toString());
console.log(" Gas price:", ethers.formatUnits(gasPrice.gasPrice || 0, "gwei"), "gwei");
const tugwar: TugWarContract = await TugWarFactory.deploy(deployer.address);
console.log("ā³ Waiting for deployment...");
await tugwar.waitForDeployment();
const contractAddress = await tugwar.getAddress();
const deploymentTx = tugwar.deploymentTransaction();
console.log("ā
Contract deployed successfully!");
console.log(" Address:", contractAddress);
console.log(" Transaction:", deploymentTx?.hash);
console.log(" Block:", deploymentTx?.blockNumber);
// Verify initial state
console.log("\nš Verifying initial state...");
try {
const gameInfo = await tugwar.getGameInfo();
console.log(" Rope position:", gameInfo.currentRopePos.toString());
console.log(" Team 1 score:", gameInfo.score1.toString());
console.log(" Team 2 score:", gameInfo.score2.toString());
console.log(" Max score diff:", gameInfo.maxDiff.toString());
console.log(" Owner:", await tugwar.owner());
console.log(" Can start game:", await tugwar.canStartGame());
} catch (error) {
console.warn("ā ļø Could not verify initial state:", error);
}
// Contract verification
console.log("\nš Contract Verification:");
console.log(" To verify manually, run:");
console.log(` npx hardhat verify --network monadTestnet ${contractAddress} "${deployer.address}"`);
// Save deployment info
const deploymentInfo = {
contractAddress: contractAddress,
deployerAddress: deployer.address,
network: network.name,
chainId: network.chainId.toString(),
transactionHash: deploymentTx?.hash,
blockNumber: deploymentTx?.blockNumber,
timestamp: new Date().toISOString(),
explorerUrl: `https://testnet.monadexplorer.com/address/${contractAddress}`
};
require('fs').writeFileSync(
'deployment.json',
JSON.stringify(deploymentInfo, null, 2)
);
console.log("š Deployment info saved to deployment.json");
// Success summary
console.log("\n" + "š".repeat(20));
console.log("š DEPLOYMENT SUCCESSFUL! š");
console.log("š".repeat(20));
console.log("\nš Summary:");
console.log(" Contract Address:", contractAddress);
console.log(" Owner:", deployer.address);
console.log(" Explorer:", deploymentInfo.explorerUrl);
console.log("\nš® Next Steps:");
console.log(" 1. Verify contract (optional)");
console.log(" 2. Test the game:", `npm run play ${contractAddress}`);
console.log(" 3. Share with players!");
console.log("\nšÆ Game Commands:");
console.log(" ⢠Pull for Team 1: tugwar.pull(true)");
console.log(" ⢠Pull for Team 2: tugwar.pull(false)");
console.log(" ⢠Check winner: tugwar.getWinStatus()");
console.log(" ⢠Reset game: tugwar.reSet(5) [owner only]");
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error("ā Deployment failed:");
console.error(error);
process.exit(1);
});
Script untuk Manual Verificationā
Buat file scripts/verify.ts
:
import { run } from "hardhat";
async function main() {
const deploymentInfo = require('../deployment.json');
const contractAddress = deploymentInfo.contractAddress;
const constructorArgs = [deploymentInfo.deployerAddress];
console.log("š Verifying TugWar contract...");
console.log(" Address:", contractAddress);
console.log(" Constructor args:", constructorArgs);
try {
await run("verify:verify", {
address: contractAddress,
constructorArguments: constructorArgs,
contract: "contracts/TugWarContract.sol:TugWarContract"
});
console.log("ā
Contract verified successfully!");
console.log("š View verified contract:");
console.log(" https://testnet.monadexplorer.com/address/" + contractAddress);
} catch (error: any) {
if (error.message.includes("Already Verified")) {
console.log("ā¹ļø Contract already verified");
console.log("š View contract:");
console.log(" https://testnet.monadexplorer.com/address/" + contractAddress);
} else {
console.error("ā Verification failed:", error.message);
console.log("\nš§ Manual verification command:");
console.log(`npx hardhat verify --network monadTestnet ${contractAddress} "${constructorArgs[0]}"`);
}
}
}
main().catch(console.error);
2. Menjalankan Deploymentā
Deploy ke Monad Testnetā
npx hardhat run scripts/deploy.ts --network monadTestnet
Output Deploymentā
š® TugWar Game Deployment to Monad Testnet
==================================================
š Deployment Info:
Deployer: 0x742d35Cc6639C0532fBaBc3CABAa1C2db582aC10
Network: monadTestnet
Chain ID: 10143
Balance: 1.234567 MON
ā
Pre-deployment checks passed
š Deploying TugWar Contract...
ā½ Gas Info:
Estimated gas: 1234567
Gas price: 20.0 gwei
ā³ Waiting for deployment...
ā
Contract deployed successfully!
Address: 0x123...ABC
Transaction: 0x456...DEF
Block: 12345
š Verifying initial state...
Rope position: 0
Team 1 score: 0
Team 2 score: 0
Max score diff: 5
Owner: 0x742d35Cc6639C0532fBaBc3CABAa1C2db582aC10
Can start game: true
š Contract Verification:
To verify manually, run:
npx hardhat verify --network monadTestnet 0x123...ABC "0x742d35Cc6639C0532fBaBc3CABAa1C2db582aC10"
š Deployment info saved to deployment.json
šššššššššššššššššššš
š DEPLOYMENT SUCCESSFUL! š
šššššššššššššššššššš
š Summary:
Contract Address: 0x123...ABC
Owner: 0x742d35Cc6639C0532fBaBc3CABAa1C2db582aC10
Explorer: https://testnet.monadexplorer.com/address/0x123...ABC
š® Next Steps:
1. Verify contract (optional)
2. Test the game: npm run play 0x123...ABC
3. Share with players!
šÆ Game Commands:
⢠Pull for Team 1: tugwar.pull(true)
⢠Pull for Team 2: tugwar.pull(false)
⢠Check winner: tugwar.getWinStatus()
⢠Reset game: tugwar.reSet(5) [owner only]
Verify Contract (Opsional)ā
npx hardhat run scripts/verify.ts --network monadTestnet
Direct Interaction via Consoleā
npx hardhat console --network monadTestnet
Di console:
// Connect to deployed contract
const tugwar = await ethers.getContractAt("TugWarContract", "0x123...ABC");
// Check game info
const gameInfo = await tugwar.getGameInfo();
console.log("Game Info:", gameInfo);
// Pull for Team 1
const tx1 = await tugwar.pull(true);
await tx1.wait();
console.log("Team 1 pulled!");
// Pull for Team 2
const tx2 = await tugwar.pull(false);
await tx2.wait();
console.log("Team 2 pulled!");
// Check winner
const winner = await tugwar.getWinStatus();
console.log("Winner:", winner); // 0 = ongoing, 1 = team1, 2 = team2
// Get prediction
const prediction = await tugwar.getPrediction();
console.log("Prediction:", prediction);
4. Package.json Scriptsā
Update package.jsonā
{
"scripts": {
"deploy": "hardhat run scripts/deploy.ts --network monadTestnet",
"verify": "hardhat run scripts/verify.ts --network monadTestnet",
"play": "hardhat run scripts/interact.ts --network monadTestnet --",
"console": "hardhat console --network monadTestnet",
"clean": "hardhat clean && rm -f deployment.json"
}
}
Usage Commandsā
# Deploy contract
npm run deploy
# Verify contract
npm run verify
# Check game status
npm run play 0x123...ABC
# Interactive console
npm run console
# Clean up
npm run clean
File Structure Hasilā
monad-tugwar-game/
āāā scripts/
ā āāā deploy.ts # Main deployment script
ā āāā verify.ts # Contract verification
ā āāā interact.ts # Game interaction
āāā deployment.json # Deployment info
āāā package.json # NPM scripts
Kesimpulanā
Selamat! Anda telah membuat deployment system yang sederhana namun lengkap untuk TugWar Game dengan:
ā Satu Script Deploymentā
- deploy.ts - All-in-one deployment dengan validation, gas estimation, dan state verification
- Automatic Checks - Balance validation dan pre-deployment verification
- State Verification - Memastikan contract ter-deploy dengan benar
- Info Saving - Menyimpan deployment info ke deployment.json
ā Supporting Scriptsā
- verify.ts - Contract verification script
- interact.ts - Game interaction dan status checking
- Console access - Direct contract interaction
ā Simple Commandsā
npm run deploy # Deploy contract
npm run verify # Verify contract
npm run play # Check game status
npm run console # Interactive mode
ā Production Readyā
- Error Handling - Comprehensive error checking
- Gas Optimization - Gas estimation dan monitoring
- Explorer Integration - Direct links ke Monad Explorer
- User Friendly - Clear instructions dan game commands
Deployment system ini memberikan workflow yang sederhana namun professional untuk deploy TugWar Game ke Monad Testnet dengan semua tools yang diperlukan untuk testing dan interaction! š®š