DeploySEALED

◆○■╲!╱◆●▒$▪~▓▒◆◇~╲╱*●~!*~@!□▓╳$□▒◇■*◇╳?▪●~~░╳#▪◆●╱%?!▫▪◇▓╳▪$╳!╲■

Transaction ID

Timestamp

Oct 26, 2025, 04:24:43 AM UTC
4mo ago

Block Height

130,656,179

Computation

0

Execution Fee

0.00000874 FLOW

Transaction Summary

Deploy

Contract deployment

Contract deployment

Script Arguments

0nameString
MMORPG8
1codeString
import FlowToken from 0x1654653399040a61 import FungibleToken from 0xf233dcee88fe0abe access(all) contract MMORPG8 { access(self) let FlowTokenVault: Capability<&{FungibleToken.Receiver}> access(self) let info: Info access(self) var totalGamePlayers: UInt // Player ID access(all) entitlement ThiefAbility1 access(all) entitlement ThiefAbility2 access(all) entitlement WarriorAbility1 access(all) entitlement WarriorAbility2 access(all) event ESportsGamerInitiated(battleId: Int, player1Address: Address, player2Address: Address) /* 構造体 */ access(all) struct Info { /* fields */ access(contract) var battleQueue: [GameBattle] access(contract) var basicAbility: {String: String} // リソース別の基本アビリティ access(contract) var basicAttackInfo: {String: [UInt8]} // システム側から通常攻撃トランザクションを行うための情報 /* setter <Return: Battle ID> */ access(contract) fun newGameBattle( player1Address: Address, player2Address: Address, lifeOfPlayer1: UInt8, lifeOfPlayer2: UInt8, reward: UFix64 ): Int { var battle = GameBattle( player1Address: player1Address, player2Address: player2Address, lifeOfPlayer1: lifeOfPlayer1, lifeOfPlayer2: lifeOfPlayer2, reward: reward ) self.battleQueue.append(battle) return self.battleQueue.length - 1 } /* setter */ access(contract) fun updateGameBattle( battleId: Int, target: String?, lifeChange: UInt8, isDamage: Bool ) { if (target != nil) { self.battleQueue[battleId]!.setPlayerLife(target: target!, lifeChange: lifeChange, isDamage: isDamage) } else { self.battleQueue[battleId]!.setEnemyLife(damage: lifeChange) // 敵への攻撃は全体攻撃しかない.. } } /* init */ init() { self.battleQueue = [] self.basicAbility = { "Warrior-BasicAttack": "Rage Attack", "Warrior-ShareableAbility": "LargeRecoveryShield", "Thief-BasicAttack": "Whip Attack", "Thief-ShareableAbility": "PoisonMaking", "Enemy-BasicAttack": "A Crushing Blow" } self.basicAttackInfo = { "Warrior": [1, 3], // [GroupAttack?, damageVolume] (Rage Attack) "Thief": [1, 1], // [GroupAttack?, damageVolume] (Whip Attack "Enemy": [0, 4] // [GroupAttack?, damageVolume] (A Crushing Blow) } } } /* Info内の構造体 */ access(all) struct GameBattle { /* fields */ access(all) let execTime: UFix64 access(all) let player1Address: Address access(all) let player2Address: Address access(all) var lifeOfPlayer1: UInt8 access(all) var lifeOfPlayer2: UInt8 access(all) var enemy1Life: UInt8 access(all) var enemy2Life: UInt8 access(all) let reward: UFix64 /* setter(ダメージまたは回復) */ access(contract) fun setPlayerLife(target: String, lifeChange: UInt8, isDamage: Bool) { if (target == "TeamPlayer1") { if (isDamage) { self.lifeOfPlayer1 = self.lifeOfPlayer1 < lifeChange ? 0 : self.lifeOfPlayer1 - lifeChange } else { self.lifeOfPlayer1 = self.lifeOfPlayer1 + lifeChange } } else if (target == "TeamPlayer2") { if (isDamage) { self.lifeOfPlayer2 = self.lifeOfPlayer2 < lifeChange ? 0 : self.lifeOfPlayer2 - lifeChange } else { self.lifeOfPlayer2 = self.lifeOfPlayer2 + lifeChange } } } /* setter(敵への全体攻撃) */ access(contract) fun setEnemyLife(damage: UInt8) { self.enemy1Life = self.enemy1Life < damage ? 0 : self.enemy1Life - damage self.enemy2Life = self.enemy2Life < damage ? 0 : self.enemy2Life - damage } /* init */ init(player1Address: Address, player2Address: Address, lifeOfPlayer1: UInt8, lifeOfPlayer2: UInt8, reward: UFix64) { let modulo: UInt8 = 3 self.execTime = getCurrentBlock().timestamp self.player1Address = player1Address self.player2Address = player2Address self.lifeOfPlayer1 = lifeOfPlayer1 self.lifeOfPlayer2 = lifeOfPlayer2 // 両方戦士タイプなら悪魔を登場させる if (lifeOfPlayer1 > 5 && lifeOfPlayer2 > 5) { self.enemy2Life = 9 + revertibleRandom(modulo: modulo) // 9 ~ 11の整数 } else { self.enemy2Life = 5 + revertibleRandom(modulo: modulo) // 5 ~ 7の整数 } self.enemy1Life = 8 + revertibleRandom(modulo: modulo) // 8 ~ 10の整数 self.reward = reward } } // GET access(all) fun getInfo(): Info { return self.info } // PUT access(all) fun newGameBattle( payment: @FlowToken.Vault, player1Address: Address, player2Address: Address, lifeOfPlayer1: UInt8, lifeOfPlayer2: UInt8 ) { let battleId = self.info.newGameBattle( player1Address: player1Address, player2Address: player2Address, lifeOfPlayer1: lifeOfPlayer1, lifeOfPlayer2: lifeOfPlayer2, reward: payment.balance * 2.0) emit ESportsGamerInitiated(battleId: battleId, player1Address: player1Address, player2Address: player2Address) // Game Feeをシステムアカウントに保存 self.FlowTokenVault.borrow()!.deposit(from: <- payment) } access(all) resource Thief { access(all) let id: UInt access(all) let maxLife: UInt8 access(ThiefAbility1) fun PoisonMaking(battleId: Int) { MMORPG8.info.updateGameBattle(battleId: battleId, target: nil, lifeChange: 6, isDamage: true) } access(ThiefAbility2) fun WhipAttack(battleId: Int) { MMORPG8.info.updateGameBattle(battleId: battleId, target: nil, lifeChange: 1, isDamage: true) } init() { MMORPG8.totalGamePlayers = MMORPG8.totalGamePlayers + 1 self.id = MMORPG8.totalGamePlayers self.maxLife = 5 } } access(all) resource Warrior { access(all) let id: UInt access(all) let maxLife: UInt8 access(WarriorAbility1) fun LargeRecoveryShield(battleId: Int, target: String) { MMORPG8.info.updateGameBattle(battleId: battleId, target: target, lifeChange: 4, isDamage: false) } access(WarriorAbility2) fun RageAttack(battleId: Int) { MMORPG8.info.updateGameBattle(battleId: battleId, target: nil, lifeChange: 3, isDamage: true) } init() { MMORPG8.totalGamePlayers = MMORPG8.totalGamePlayers + 1 self.id = MMORPG8.totalGamePlayers self.maxLife = 8 } } access(all) resource Admin { access(all) fun payRewards(recipient1: Address, recipient2: Address, reward: UFix64) { // Pay the reward. let reward1 <- MMORPG8.account .storage .borrow<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>(from: /storage/flowTokenVault)! .withdraw(amount: reward) as! @FlowToken.Vault getAccount(recipient1) .capabilities .get<&{FungibleToken.Receiver}>(/public/flowTokenReceiver) .borrow()!.deposit(from: <- reward1) let reward2 <- MMORPG8.account .storage .borrow<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>(from: /storage/flowTokenVault)! .withdraw(amount: reward) as! @FlowToken.Vault getAccount(recipient2) .capabilities .get<&{FungibleToken.Receiver}>(/public/flowTokenReceiver) .borrow()!.deposit(from: <- reward2) } access(all) fun basicAttack(battleId: Int, target: String?, resourceName: String) { MMORPG8.info.updateGameBattle(battleId: battleId, target: target, lifeChange: MMORPG8.info.basicAttackInfo[resourceName]![1], isDamage: true) } } access(all) fun createWarriorResource(payment: @FlowToken.Vault): @MMORPG8.Warrior { pre { payment.balance == 5.0: "Cost of resource must be 5.0FLOW coin." } let _resource <- create Warrior() // resourceは予約語なので_をつけてます MMORPG8.FlowTokenVault.borrow()!.deposit(from: <- payment) // 代金徴収 return <- _resource } access(all) fun createThiefResource(payment: @FlowToken.Vault): @MMORPG8.Thief { pre { payment.balance == 5.0: "Cost of resource must be 5.0FLOW coin." } let _resource <- create Thief() MMORPG8.FlowTokenVault.borrow()!.deposit(from: <- payment) // 代金徴収 return <- _resource } init() { self.info = Info() self.FlowTokenVault = self.account.capabilities.get<&{FungibleToken.Receiver}>(/public/flowTokenReceiver) self.totalGamePlayers = 0 self.account.storage.save( <- create Admin(), to: /storage/MMORPG8Admin) } }

Cadence Script

1transaction(name: String, code: String ) {
2		prepare(signer: auth(AddContract) &Account) {
3			signer.contracts.add(name: name, code: code.utf8 )
4		}
5	}