diff --git a/mover/klren0312/code/faucet_coin/Move.lock b/mover/klren0312/code/faucet_coin/Move.lock index 777b96dbd..a4c28d870 100644 --- a/mover/klren0312/code/faucet_coin/Move.lock +++ b/mover/klren0312/code/faucet_coin/Move.lock @@ -24,23 +24,3 @@ dependencies = [ compiler-version = "1.37.1" edition = "2024.beta" flavor = "sui" - -[env] - -[env.Testnet] -chain-id = "4c78adac" -original-published-id = "0x61d55cb78c34919cafa8c42ad7dbf061a9e642d99774780f11f1f1f6cde3050f" -latest-published-id = "0x61d55cb78c34919cafa8c42ad7dbf061a9e642d99774780f11f1f1f6cde3050f" -published-version = "1" - -[env.Devnet] -chain-id = "e8c8eaba" -original-published-id = "0x4fedce78232abcb4e0004676c7cd589132b44bd57ad4ba89dd000de17edd9e05" -latest-published-id = "0x4fedce78232abcb4e0004676c7cd589132b44bd57ad4ba89dd000de17edd9e05" -published-version = "1" - -[env.Mainnet] -chain-id = "35834a8a" -original-published-id = "0xc9fbe1280a650aecbfdad2a06fcb3d9caee10c07a1c0ae405e8494727d3a29a5" -latest-published-id = "0xc9fbe1280a650aecbfdad2a06fcb3d9caee10c07a1c0ae405e8494727d3a29a5" -published-version = "1" diff --git a/mover/klren0312/code/faucet_coin/sources/faucet_coin.move b/mover/klren0312/code/faucet_coin/sources/faucet_coin.move index e67e7003a..bb72196eb 100644 --- a/mover/klren0312/code/faucet_coin/sources/faucet_coin.move +++ b/mover/klren0312/code/faucet_coin/sources/faucet_coin.move @@ -34,6 +34,15 @@ module faucet_coin::TRUMP_COIN { transfer::share_object(publicWallet); } + // 修改水龙头一次获取数量 + public entry fun set_faucet_amount( + wallet: &mut Public_Wallet, + amount: u64, + _ctx: &mut TxContext + ) { + wallet.faucet_amount = amount; + } + // 创建水龙头 public entry fun create_faucet( treasury_cap: &mut TreasuryCap, diff --git a/mover/klren0312/code/move_game/Move.lock b/mover/klren0312/code/move_game/Move.lock new file mode 100644 index 000000000..e72d3e986 --- /dev/null +++ b/mover/klren0312/code/move_game/Move.lock @@ -0,0 +1,43 @@ +# @generated by Move, please check-in and do not edit manually. + +[move] +version = 3 +manifest_digest = "14727144350BE98A1776A6A45FF824840C48219D5F18A98AD5127B3A41274ED8" +deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" +dependencies = [ + { id = "Sui", name = "Sui" }, + { id = "faucet_coin", name = "faucet_coin" }, +] + +[[move.package]] +id = "MoveStdlib" +source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/mainnet", subdir = "crates/sui-framework/packages/move-stdlib" } + +[[move.package]] +id = "Sui" +source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/mainnet", subdir = "crates/sui-framework/packages/sui-framework" } + +dependencies = [ + { id = "MoveStdlib", name = "MoveStdlib" }, +] + +[[move.package]] +id = "faucet_coin" +source = { git = "https://github.com/move-cn/letsmove.git", rev = "main", subdir = "mover/klren0312/code/faucet_coin" } + +dependencies = [ + { id = "Sui", name = "Sui" }, +] + +[move.toolchain-version] +compiler-version = "1.37.1" +edition = "2024.beta" +flavor = "sui" + +[env] + +[env.Mainnet] +chain-id = "35834a8a" +original-published-id = "0x413e80e5c694ee898cdb34ba412365702f2d7b5d5f2d0f3c6ccc40f89bdbb066" +latest-published-id = "0x413e80e5c694ee898cdb34ba412365702f2d7b5d5f2d0f3c6ccc40f89bdbb066" +published-version = "1" diff --git a/mover/klren0312/code/move_game/Move.toml b/mover/klren0312/code/move_game/Move.toml new file mode 100644 index 000000000..4954699cc --- /dev/null +++ b/mover/klren0312/code/move_game/Move.toml @@ -0,0 +1,41 @@ +[package] +name = "move_game" +edition = "2024.beta" # edition = "legacy" to use legacy (pre-2024) Move +# license = "" # e.g., "MIT", "GPL", "Apache 2.0" +# authors = ["..."] # e.g., ["Joe Smith (joesmith@noemail.com)", "John Snow (johnsnow@noemail.com)"] + +[dependencies] +Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "framework/mainnet" } +# 引入线上水龙头币合约 +faucet_coin = { git = "https://github.com/move-cn/letsmove.git", subdir = "mover/klren0312/code/faucet_coin", rev = "main" } +# 引入本地水龙头币合约 +# faucet_coin = { local = "../faucet_coin", override = true} + +# For remote import, use the `{ git = "...", subdir = "...", rev = "..." }`. +# Revision can be a branch, a tag, and a commit hash. +# MyRemotePackage = { git = "https://some.remote/host.git", subdir = "remote/path", rev = "main" } + +# For local dependencies use `local = path`. Path is relative to the package root +# Local = { local = "../path/to" } + +# To resolve a version conflict and force a specific version for dependency +# override use `override = true` +# Override = { local = "../conflicting/version", override = true } + +[addresses] +move_game = "0x0" + +# Named addresses will be accessible in Move as `@name`. They're also exported: +# for example, `std = "0x1"` is exported by the Standard Library. +# alice = "0xA11CE" + +[dev-dependencies] +# The dev-dependencies section allows overriding dependencies for `--test` and +# `--dev` modes. You can introduce test-only dependencies here. +# Local = { local = "../path/to/dev-build" } + +[dev-addresses] +# The dev-addresses section allows overwriting named addresses for the `--test` +# and `--dev` modes. +# alice = "0xB0B" + diff --git a/mover/klren0312/code/move_game/sources/move_game.move b/mover/klren0312/code/move_game/sources/move_game.move new file mode 100644 index 000000000..670d67b29 --- /dev/null +++ b/mover/klren0312/code/move_game/sources/move_game.move @@ -0,0 +1,144 @@ +module move_game::klren0312_game { + use sui::coin::{Self, Coin, value, from_balance}; + use sui::balance::{Self, Balance}; // 余额操作 + use faucet_coin::TRUMP_COIN::TRUMP_COIN; // 水龙头币 + use sui::tx_context::sender; + // Random has a reserved address 0x8 + use sui::random::{ Random, new_generator, generate_u8_in_range }; + use sui::event::{emit}; + use std::string::{utf8, String}; + + // 错误码 + const ErrorAddrBalanceInsufficient: u64 = 0; // 钱包余额不足 + const ErrorGameServerBalanceInsufficient: u64 = 1; // 游戏服务器余额不足 + + + // 管理员权限 + public struct AdminCap has key { + id: UID + } + + // 游戏服务 + public struct GameServer has key { + id: UID, + coin_pool: Balance, + need_coin_amount: u64, // 玩需要的钱 + reward_coin: u64 // 奖励的钱 + } + + // 游戏结果 + public struct GameResult has copy, drop { + game_server_number: u8, + player_guess_number: u8, + play_status: bool, + play_status_chinese: String, + reward_coin_amount: u64 + } + + // 生成游戏服务 + entry fun gen_game(amount: u64, ctx: &mut TxContext) { + // 共享gameserver + let gameServer = GameServer { + id: object::new(ctx), + coin_pool: balance::zero(), + need_coin_amount: amount, + reward_coin: amount * 2 + }; + transfer::share_object(gameServer); + + // 转移管理员权限给发送的人 + let admin_cap = AdminCap { + id: object::new(ctx) + }; + transfer::transfer(admin_cap, sender(ctx)); + } + + // 开始玩 + entry fun do_play (r: &Random, game_server: &mut GameServer, input_addr_coin_type: Coin, guess: u8, ctx: &mut TxContext) { + // 先把玩游戏的钱存到游戏服务器 + let amount = game_server.need_coin_amount; // 转一下 防止下面报错 + deposit(game_server, input_addr_coin_type, amount, ctx); + + let mut gen = new_generator(r, ctx); + // 生成游戏服务器的随机数结果 + let server_number: u8 = generate_u8_in_range(&mut gen, 1, 10); + + // 游戏状态 true-赢 false-输 + let mut play_result: bool = false; + // 相等,就是赢 + if (guess == server_number) { + // 获取游戏服务器资金池的余额数量 + let coin_pool_amount = balance::value(&game_server.coin_pool); + // 余额不够支付,报错 + assert!(game_server.reward_coin <= coin_pool_amount, ErrorGameServerBalanceInsufficient); + + // 从游戏服务器的资金池中分出来奖励的余额 + let reward_balance = balance::split(&mut game_server.coin_pool, game_server.reward_coin); + let reward_coin = coin::from_balance(reward_balance, ctx); + // 发给玩游戏的人 + transfer::public_transfer(reward_coin, sender(ctx)); + play_result = true; + }; + let mut reward_coin_amount: u64 = 0; + let mut play_status_chinese: String = utf8(b"输了"); + if (play_result == true) { + reward_coin_amount = game_server.reward_coin; + play_status_chinese = utf8(b"赢了"); + }; + // 发送游戏结果事件 + emit(GameResult{ + game_server_number: server_number, + player_guess_number: guess, + play_status: play_result, + play_status_chinese: play_status_chinese, + reward_coin_amount: reward_coin_amount + }); + } + + + // 给服务器存款 + entry fun deposit(game_server: &mut GameServer, input_addr_coin_type: Coin, amount: u64, ctx: &mut TxContext) { + // 获取存款账户当前TRUMP_COIN的余额 + let current_addr_coin = value(&input_addr_coin_type); + // 存的钱大于自己本身的余额,报错 + assert!(current_addr_coin >= amount, ErrorAddrBalanceInsufficient); + // 从存款账户中提取出余额 + let mut current_addr_balance = coin::into_balance(input_addr_coin_type); + // 如果存款账户的余额大于存款的钱,需要分割存款账户余额,提取存的钱那部分余额,存到游戏服务器的资金池 + if (current_addr_coin > amount) { + balance::join( + &mut game_server.coin_pool, + balance::split(&mut current_addr_balance, amount) + ); + // 把剩下的余额转成coin,用于转发回存款账户的钱包里 + let finish_current_addr_coin = from_balance(current_addr_balance, ctx); + transfer::public_transfer(finish_current_addr_coin, sender(ctx)); + } else { + // 如果存款账户的余额等于存款的钱,直接放到游戏服务器资金池 + balance::join( + &mut game_server.coin_pool, + current_addr_balance + ); + } + } + + // 用于服务管理员从服务器提款 + entry fun admin_withdraw(_: &AdminCap, game_server: &mut GameServer, amount: u64, ctx: &mut TxContext) { + // 获取游戏服务器资金池的余额数量 + let coin_pool_amount = balance::value(&game_server.coin_pool); + // 余额不够支付,报错 + assert!(amount <= coin_pool_amount, ErrorGameServerBalanceInsufficient); + // 提取出指定数量余额 + let withdraw_balance = balance::split(&mut game_server.coin_pool, amount); + // 余额转成coin + let withdraw_coin = from_balance(withdraw_balance , ctx); + // 发给管理员账户 + transfer::public_transfer(withdraw_coin, sender(ctx)); + } + + #[test_only] + entry fun get_random(r: &Random, ctx: &mut TxContext): u8 { + let mut gen = new_generator(r, ctx); + generate_u8_in_range(&mut gen, 10, 20) + } +} diff --git a/mover/klren0312/code/move_game/tests/move_game_tests.move b/mover/klren0312/code/move_game/tests/move_game_tests.move new file mode 100644 index 000000000..de7b14731 --- /dev/null +++ b/mover/klren0312/code/move_game/tests/move_game_tests.move @@ -0,0 +1,29 @@ +#[test_only] +module move_game::move_game_tests; +// uncomment this line to import the module +use move_game::klren0312_game::{get_random}; +use std::debug::print; +use sui::test_scenario as ts; +use sui::random::{Random, create_for_testing}; + +#[test] +fun test_get_random() { + let user = @0x0; + let mut ts = ts::begin(user); + create_for_testing(ts.ctx()); + ts.next_tx(user); + let mut random_state: Random = ts.take_shared(); + random_state.update_randomness_state_for_testing(0, x"feaafeaafeaafeaa", ts.ctx()); + let number = get_random(&random_state, ts.ctx()); + print(&number); + random_state.update_randomness_state_for_testing(1, x"feaafeaafeaafeaa", ts.ctx()); + let number2 = get_random(&random_state, ts.ctx()); + print(&number2); + random_state.update_randomness_state_for_testing(2, x"feaafeaafeaafeaa", ts.ctx()); + let number3 = get_random(&random_state, ts.ctx()); + print(&number3); + ts::return_shared(random_state); + ts.end(); +} + + diff --git a/mover/klren0312/readme.md b/mover/klren0312/readme.md index b31b01580..1fafd6623 100644 --- a/mover/klren0312/readme.md +++ b/mover/klren0312/readme.md @@ -31,10 +31,10 @@ - [x] scan上的NFT截图:![Scan截图](./images/03movenft/scan上的NFT截图.png) ## 04 Move Game -- [] game package id : -- [] deposit Coin hash: -- [] withdraw `Coin` hash: -- [] play game hash: +- [x] game package id: [0x413e80e5c694ee898cdb34ba412365702f2d7b5d5f2d0f3c6ccc40f89bdbb066](https://suiscan.xyz/mainnet/object/0x413e80e5c694ee898cdb34ba412365702f2d7b5d5f2d0f3c6ccc40f89bdbb066) +- [x] deposit Coin hash: [F8SrvkmhmXoCozCJdMCEeLVpco9WRLv4Nc7P8JBwsJk1](https://suiscan.xyz/mainnet/tx/F8SrvkmhmXoCozCJdMCEeLVpco9WRLv4Nc7P8JBwsJk1) +- [x] withdraw `Coin` hash: [2kcQf8D3KaDqdwU6rgBpddVuGA7E1ccvfM14XmqubzFd](https://suiscan.xyz/mainnet/tx/2kcQf8D3KaDqdwU6rgBpddVuGA7E1ccvfM14XmqubzFd) +- [x] play game hash: [JALk1BLnrTyTAV71cDZ3Be2AJPqaJYZ1WM47yT4ux4PQ](https://suiscan.xyz/mainnet/tx/JALk1BLnrTyTAV71cDZ3Be2AJPqaJYZ1WM47yT4ux4PQ) ## 05 Move Swap - [] swap package id :