diff --git a/mover/HlLming/code/task4/Move.toml b/mover/HlLming/code/task4/Move.toml new file mode 100644 index 000000000..86e124a47 --- /dev/null +++ b/mover/HlLming/code/task4/Move.toml @@ -0,0 +1,37 @@ +[package] +name = "task4" +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/testnet" } + +# 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] +task4 = "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/HlLming/code/task4/sources/task4.move b/mover/HlLming/code/task4/sources/task4.move new file mode 100644 index 000000000..224c560e9 --- /dev/null +++ b/mover/HlLming/code/task4/sources/task4.move @@ -0,0 +1,170 @@ +module task4::hllming_game { + use std::string::{Self, String}; + use sui::event; + use sui::balance::{Self, Balance}; + use sui::coin::{Self, Coin}; + use sui::tx_context::sender; + use std::hash; + use sui::bcs; + + const EPoolNotEnough: u64 = 1; + const EInputNotEnough: u64 = 2; + const ERR_HIGH_ARG_GREATER_THAN_LOW_ARG: u64 = 101; + + public struct GameResult has copy, drop { + result: String, + is_winner: bool, + } + + public struct Game has key { + id: UID, + pool: Balance, + ticket: u64, + reward: u64, + } + + public struct SpinResult has copy, drop, store { + spin1: u8, + spin2: u8, + spin3: u8, + } + + public fun game_pool(game: &Game): u64 { + balance::value(&game.pool) + } + + public fun game_ticket(game: &Game): u64 { + game.ticket + } + + public fun game_reward(game: &Game): u64 { + game.reward + } + + public struct AdminCap has key { + id: UID, + } + + fun init(_ctx: &mut TxContext) { + } + + entry fun creat_game(ctx: &mut TxContext) { + let game = Game { + id: object::new(ctx), + pool: balance::zero(), + ticket: 1000, + reward: 2000, + }; + transfer::share_object(game); + + let admin_cap = AdminCap { id: object::new(ctx) }; + transfer::transfer(admin_cap, sender(ctx)); + } + + fun get_spin_result(ctx: &mut TxContext) : SpinResult { + let spin1 = (rand_u64_range(0, 5, ctx) as u8); + let spin2 = (rand_u64_range(0, 5, ctx) as u8); + let spin3 = (rand_u64_range(0, 5, ctx) as u8); + SpinResult { spin1, spin2, spin3 } + } + + public entry fun play(game: &mut Game, input: Coin, ctx: &mut TxContext) { + assert!(balance::value(&game.pool) >= game.reward - game.ticket, EPoolNotEnough); + + let player_spins = get_spin_result(ctx); + let winning_combination = SpinResult { spin1: 2, spin2: 2, spin3: 2 }; + + let input_value = coin::value(&input); + assert!(input_value >= game.ticket, EInputNotEnough); + + let mut input_balance = coin::into_balance(input); + if (input_value > game.ticket) { + balance::join( + &mut game.pool, + balance::split(&mut input_balance, game.ticket) + ); + let change = coin::from_balance(input_balance, ctx); + transfer::public_transfer(change, sender(ctx)); + } else { + balance::join(&mut game.pool, input_balance); + }; + + let (result, is_winner) = if (player_spins.spin1 == winning_combination.spin1 && player_spins.spin2 == winning_combination.spin2 && player_spins.spin3 == winning_combination.spin3) { + ( string::utf8(b"Congratulations, you hit the jackpot! Collect your coins😄"), true) + } else { + ( string::utf8(b"Try again, better luck next time!💔"), false) + }; + + if (is_winner) { + let reward_balance = balance::split(&mut game.pool, game.reward); + let reward = coin::from_balance(reward_balance, ctx); + transfer::public_transfer(reward, sender(ctx)); + }; + + event::emit(GameResult { + result, + is_winner, + }); + } + + public entry fun deposit(game: &mut Game, input: Coin, amount: u64, ctx: &mut TxContext) { + let input_value = coin::value(&input); + assert!(input_value >= amount, EInputNotEnough); + + let mut input_balance = coin::into_balance(input); + if (input_value > amount) { + balance::join( + &mut game.pool, + balance::split(&mut input_balance, amount) + ); + let change = coin::from_balance(input_balance, ctx); + transfer::public_transfer(change, sender(ctx)); + } else { + balance::join(&mut game.pool, input_balance); + } + } + + public entry fun withdraw(_: &AdminCap, game: &mut Game, amount: u64, ctx: &mut TxContext) { + let output_balance = balance::split(&mut game.pool, amount); + let output = coin::from_balance(output_balance, ctx); + transfer::public_transfer(output, sender(ctx)); + } + + fun seed(ctx: &mut TxContext): vector { + let ctx_bytes = bcs::to_bytes(ctx); + let uid = object::new(ctx); + let uid_bytes: vector = object::uid_to_bytes(&uid); + object::delete(uid); + + let mut info: vector = vector::empty(); + vector::append(&mut info, ctx_bytes); + vector::append(&mut info, uid_bytes); + + let hash: vector = hash::sha3_256(info); + hash + } + + fun bytes_to_u64(bytes: vector): u64 { + let mut value = 0u64; + let mut i = 0u64; + while (i < 8) { + value = value | ((*vector::borrow(&bytes, i) as u64) << ((8 * (7 - i)) as u8)); + i = i + 1; + }; + return value + } + + fun rand_u64_with_seed(_seed: vector): u64 { + bytes_to_u64(_seed) + } + + fun rand_u64_range_with_seed(_seed: vector, low: u64, high: u64): u64 { + assert!(high > low, ERR_HIGH_ARG_GREATER_THAN_LOW_ARG); + let value = rand_u64_with_seed(_seed); + (value % (high - low)) + low + } + + public fun rand_u64_range(low: u64, high: u64, ctx: &mut TxContext): u64 { + rand_u64_range_with_seed(seed(ctx), low, high) + } +} \ No newline at end of file diff --git a/mover/HlLming/code/task5/Move.toml b/mover/HlLming/code/task5/Move.toml new file mode 100644 index 000000000..856a08c66 --- /dev/null +++ b/mover/HlLming/code/task5/Move.toml @@ -0,0 +1,37 @@ +[package] +name = "task5" +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/testnet" } + +# 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] +task5 = "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/HlLming/code/task5/sources/task5.move b/mover/HlLming/code/task5/sources/task5.move new file mode 100644 index 000000000..f141a84df --- /dev/null +++ b/mover/HlLming/code/task5/sources/task5.move @@ -0,0 +1,312 @@ +module task5::hllming_swap { + use sui::object::{Self, UID}; + use sui::coin::{Self, Coin}; + use sui::balance::{Self, Supply, Balance}; + use sui::transfer; + use sui::math; + use sui::tx_context::{Self, TxContext}; + + /// For when supplied Coin is zero. + const EZeroAmount: u64 = 0; + + /// For when someone tries to swap in an empty pool. + const EReservesEmpty: u64 = 2; + + /// For when someone attempts to add more liquidity than u128 Math allows. + const EPoolFull: u64 = 4; + + /// The integer scaling setting for fees calculation. + const FEE_SCALING: u128 = 10000; + + /// The fee percent that will be taken from the swap. + /// Set to 0.3%. + const FEE_PERCENT: u128 = 30; + + /// The max value that can be held in one of the Balances of + /// a Pool. U64 MAX / FEE_SCALING + const MAX_POOL_VALUE: u64 = { + 18446744073709551615 / 10000 + }; + + /// The Pool token that will be used to mark the pool share + /// of a liquidity provider. + /// The first type parameter stands for the witness type of a pool. + /// The seconds and thirds is for the coin held in the pool. + public struct LSP has drop {} + + /// The pool with exchange. + /// + /// - `fee_percent` should be in the range: [0-10000), meaning + /// that 10000 is 100% and 1 is 0.01% + public struct Pool has key { + id: UID, + token_a: Balance, + token_b: Balance, + lsp_supply: Supply>, + /// Fee Percent is denominated in basis points. + fee_percent: u64 + } + + + /// ======================================================================= + /// ============================= 初始化函数 =============================== + /// ======================================================================= + + /// Module initializer is empty - to publish a new Pool one has + /// to create a type which will mark LSPs. + fun init(_: &mut TxContext) { + } + + /// ======================================================================= + /// ============================= 流动性池 ================================= + /// ======================================================================= + + entry fun create_pool ( + token_a: Coin, + token_b: Coin, + ctx: &mut TxContext + ) { + transfer::public_transfer( + create_pool_inner(token_a, token_b, ctx), + tx_context::sender(ctx) + ); + } + + fun create_pool_inner ( + token_a: Coin, + token_b: Coin, + ctx: &mut TxContext + ): Coin> { + let fee_percent = (FEE_PERCENT as u64); + + let token_a_amt = coin::value(&token_a); + let token_b_amt = coin::value(&token_b); + + assert!(token_a_amt > 0 && token_b_amt > 0, EZeroAmount); + assert!(token_a_amt < MAX_POOL_VALUE && token_b_amt < MAX_POOL_VALUE, EPoolFull); + + let share = math::sqrt(token_a_amt) * math::sqrt(token_b_amt); + let mut lsp_supply = balance::create_supply(LSP {}); + let lsp = balance::increase_supply(&mut lsp_supply, share); + + transfer::share_object(Pool { + id: object::new(ctx), + token_a: coin::into_balance(token_a), + token_b: coin::into_balance(token_b), + lsp_supply, + fee_percent, + }); + + coin::from_balance(lsp, ctx) + } + + entry fun add_liquidity ( + pool: &mut Pool, + token_a: Coin, + token_b: Coin, + ctx: &mut TxContext + ) { + transfer::public_transfer( + add_liquidity_inner(pool, token_a, token_b, ctx), + tx_context::sender(ctx) + ) + } + + fun add_liquidity_inner ( + pool: &mut Pool, + token_a: Coin, + token_b: Coin, + ctx: &mut TxContext + ): Coin> { + assert!(coin::value(&token_a) > 0 && coin::value(&token_b) > 0, EZeroAmount); + + let (token_a_amt, token_b_amt, lsp_supply) = get_amounts(pool); + assert!(token_a_amt > 0 && token_b_amt > 0, EReservesEmpty); + + let token_a_balance = coin::into_balance(token_a); + let token_b_balance = coin::into_balance(token_b); + + let token_a_added = balance::value(&token_a_balance); + let token_b_added = balance::value(&token_b_balance); + + // XXX - 可以对新增的流动性进行计算,查看比值是否和原来的比值一致 + // assert!(token_a_added * token_b_amt == token_b_added * token_a_amt, EWrongFee); + // assert!(math::abs_diff(token_a_added * token_b_amt, token_b_added * token_a_amt) < 100, EWrongFee); + + let share_minted = math::min( + (token_a_added * lsp_supply) / token_a_amt, + (token_b_added * lsp_supply) / token_b_amt + ); + + let token_a_amt = balance::join(&mut pool.token_a, token_a_balance); + let token_b_amt = balance::join(&mut pool.token_b, token_b_balance); + + assert!(token_a_amt < MAX_POOL_VALUE && token_b_amt < MAX_POOL_VALUE, EPoolFull); + + let balance = balance::increase_supply(&mut pool.lsp_supply, share_minted); + + coin::from_balance(balance, ctx) + } + + entry fun remove_liquidity ( + pool: &mut Pool, + lsp: Coin>, + ctx: &mut TxContext + ) { + let (token_a, token_b) = remove_liquidity_inner(pool, lsp, ctx); + let sender = tx_context::sender(ctx); + + transfer::public_transfer(token_a, sender); + transfer::public_transfer(token_b, sender); + } + + fun remove_liquidity_inner ( + pool: &mut Pool, + lsp: Coin>, + ctx: &mut TxContext + ): (Coin, Coin) { + let lsp_amount = coin::value(&lsp); + assert!(lsp_amount > 0, EZeroAmount); + + let (token_a_amt, token_b_amt, total_supply) = get_amounts(pool); + + let token_a = (token_a_amt * lsp_amount) / total_supply; + let token_b = (token_b_amt * lsp_amount) / total_supply; + + balance::decrease_supply(&mut pool.lsp_supply, coin::into_balance(lsp)); + + ( + coin::take(&mut pool.token_a, token_a, ctx), + coin::take(&mut pool.token_b, token_b, ctx), + ) + } + + /// ======================================================================= + /// ============================= 交易函数 ================================= + /// ======================================================================= + + entry fun swap_a_to_b ( + pool: &mut Pool, + token_a: Coin, + ctx: &mut TxContext + ) { + transfer::public_transfer( + swap_a_to_b_inner(pool, token_a, ctx), + tx_context::sender(ctx) + ) + } + + fun swap_a_to_b_inner ( + pool: &mut Pool, + token_a: Coin, + ctx: &mut TxContext + ): Coin { + let token_a_amt = coin::value(&token_a); + assert!(token_a_amt > 0, EZeroAmount); + + let (token_a_amt, token_b_amt, _) = get_amounts(pool); + assert!(token_a_amt > 0 && token_b_amt > 0, EReservesEmpty); + + let token_b_amt = sell_token_a(pool, token_a_amt); + + balance::join(&mut pool.token_a, coin::into_balance(token_a)); + + coin::take(&mut pool.token_b, token_b_amt, ctx) + } + + entry fun swap_b_to_a ( + pool: &mut Pool, + token_b: Coin, + ctx: &mut TxContext + ) { + transfer::public_transfer( + swap_b_to_a_inner(pool, token_b, ctx), + tx_context::sender(ctx) + ) + } + + fun swap_b_to_a_inner ( + pool: &mut Pool, + token_b: Coin, + ctx: &mut TxContext + ): Coin { + let token_b_amt = coin::value(&token_b); + assert!(token_b_amt > 0, EZeroAmount); + + let (token_a_amt, token_b_amt, _) = get_amounts(pool); + assert!(token_a_amt > 0 && token_b_amt > 0, EReservesEmpty); + + let token_a_amt = sell_token_b(pool, token_b_amt); + + balance::join(&mut pool.token_b, coin::into_balance(token_b)); + + coin::take(&mut pool.token_a, token_a_amt, ctx) + } + + /// ======================================================================= + /// ============================= 辅助函数 ================================= + /// ======================================================================= + + /// 计算售出指定数量的 Token A,会得到多少数量的 Token B + public fun sell_token_a(pool: &Pool, to_sell: u64): u64 { + let (token_a_amt, token_b_amt, _) = get_amounts(pool); + calc_output_amount( + to_sell, + token_a_amt, + token_b_amt, + pool.fee_percent + ) + } + + /// 计算售出指定数量的 Token B,会得到多少数量的 Token A + public fun sell_token_b(pool: &Pool, to_sell: u64): u64 { + let (token_a_amt, token_b_amt, _) = get_amounts(pool); + calc_output_amount( + to_sell, + token_b_amt, + token_a_amt, + pool.fee_percent + ) + } + + /// Get most used values in a handy way: + /// - amount of token a + /// - amount of token b + /// - total supply of LSP + public fun get_amounts(pool: &Pool): (u64, u64, u64) { + ( + balance::value(&pool.token_a), + balance::value(&pool.token_b), + balance::supply_value(&pool.lsp_supply), + ) + } + + public fun calc_output_amount( + input_amount: u64, + input_reserve: u64, + output_reserve: u64, + fee_percent: u64 + ): u64 { + let ( + input_amount, + input_reserve, + output_reserve, + fee_percent + ) = ( + (input_amount as u128), + (input_reserve as u128), + (output_reserve as u128), + (fee_percent as u128), + ); + + // 计算手续费后的输入数量 + let input_with_fee = input_amount * FEE_SCALING / (FEE_SCALING - fee_percent); + + // 根据公式 (x + dx) * (y - dy) = k + // 得到 dy = y - k / (x + dx) + let total = input_reserve * output_reserve; + let output_amount = output_reserve - total / (input_reserve + input_with_fee); + + (output_amount as u64) + } +} diff --git a/mover/HlLming/code/task6/index.html b/mover/HlLming/code/task6/index.html new file mode 100644 index 000000000..251e0801f --- /dev/null +++ b/mover/HlLming/code/task6/index.html @@ -0,0 +1,12 @@ + + + + + + SDK Help + + +
+ + + diff --git a/mover/HlLming/code/task6/package.json b/mover/HlLming/code/task6/package.json new file mode 100644 index 000000000..076a96228 --- /dev/null +++ b/mover/HlLming/code/task6/package.json @@ -0,0 +1,24 @@ +{ + "name": "with-vite", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite --port 3000" + }, + "dependencies": { + "@mysten/sui.js": "0.51.2", + "@suiet/wallet-kit": "0.2.24", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "tweetnacl": "^1.0.3", + "navi-sdk": "^1.1.21" + }, + "devDependencies": { + "@types/react": "^18.0.22", + "@types/react-dom": "^18.0.7", + "@vitejs/plugin-react": "^2.2.0", + "typescript": "^5.4.3", + "vite": "^3.2.7" + } +} diff --git a/mover/HlLming/code/task6/src/App.css b/mover/HlLming/code/task6/src/App.css new file mode 100644 index 000000000..ac87691e7 --- /dev/null +++ b/mover/HlLming/code/task6/src/App.css @@ -0,0 +1,43 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.card { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 2em; +} + +.read-the-docs { + color: #888; +} + +.btn-group button+button{ + margin-left: 12px; +} \ No newline at end of file diff --git a/mover/HlLming/code/task6/src/App.tsx b/mover/HlLming/code/task6/src/App.tsx new file mode 100644 index 000000000..c2c8462cf --- /dev/null +++ b/mover/HlLming/code/task6/src/App.tsx @@ -0,0 +1,114 @@ +import "./App.css"; +import { + ConnectButton, + useAccountBalance, + useWallet, + ErrorCode, + formatSUI, +} from "@suiet/wallet-kit"; +import "@suiet/wallet-kit/style.css"; +import { TransactionBlock } from "@mysten/sui.js/transactions"; +import {depositCoin, borrowCoin} from 'navi-sdk/dist/libs/PTB' +import { Pool, PoolConfig } from "navi-sdk/dist/types"; +import { pool } from 'navi-sdk/dist/address' +import {Sui, USDC} from 'navi-sdk/dist/address'; + +function App() { + const wallet = useWallet(); + const { balance } = useAccountBalance(); + + function uint8arrayToHex(value: Uint8Array | undefined) { + if (!value) return ""; + // @ts-ignore + return value.toString("hex"); + } + + async function handleNAVISDK() { + if (!wallet.account) return; + const account = wallet.account; + const sender = account.address; + try { + let txb = new TransactionBlock(); + txb.setSender(sender); + + let getCoinInfo = balance; + if (!getCoinInfo) { + throw new Error("Insufficient balance"); + } + + let deposit_amount = 1e9; + let sui_symbol = Sui.symbol; + const pool_sui: PoolConfig = pool[sui_symbol as keyof Pool]; + const [to_deposit] = txb.splitCoins(txb.gas, [deposit_amount]); + await depositCoin(txb, pool_sui, to_deposit, deposit_amount); + + let borrow_amount = 0.072817 * 1e6; + let usdc_symbol = USDC.symbol; + const pool_usdc: PoolConfig = pool[usdc_symbol as keyof Pool]; + const [borrow_coin] = await borrowCoin(txb, pool_usdc, borrow_amount); + + await depositCoin(txb, pool_usdc, borrow_coin, borrow_amount); + + const resData = await wallet.signAndExecuteTransactionBlock({ + transactionBlock: txb, + }); + console.log("transaction digest: " + JSON.stringify(resData)); + } catch (e) { + console.error("failed", e); + alert("failed (see response in the console)"); + } + } + + return ( +
+
+ { + if (error.code === ErrorCode.WALLET__CONNECT_ERROR__USER_REJECTED) { + console.warn( + "user rejected the connection to " + error.details?.wallet + ); + } else { + console.warn("unknown connect error: ", error); + } + }} + /> + + {!wallet.connected ? ( +

Connect wallet from now!

+ ) : ( +
+
+

current wallet: {wallet.adapter?.name}

+

+ wallet status:{" "} + {wallet.connecting + ? "connecting" + : wallet.connected + ? "connected" + : "disconnected"} +

+

wallet address: {wallet.account?.address}

+

current network: {wallet.chain?.name}

+

+ wallet balance:{" "} + {formatSUI(balance ?? 0, { + withAbbr: false, + })}{" "} + SUI +

+

+ wallet publicKey: {uint8arrayToHex(wallet.account?.publicKey)} +

+
+
+ +
+
+ )} +
+
+ ); +} + +export default App; diff --git a/mover/HlLming/code/task6/src/main.tsx b/mover/HlLming/code/task6/src/main.tsx new file mode 100644 index 000000000..b27eb00c3 --- /dev/null +++ b/mover/HlLming/code/task6/src/main.tsx @@ -0,0 +1,16 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App' +import './index.css' + +import { + WalletProvider, +} from '@suiet/wallet-kit'; + +ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + + + + + +) diff --git a/mover/HlLming/notes/s.png b/mover/HlLming/notes/s.png new file mode 100644 index 000000000..3370e3ab2 Binary files /dev/null and b/mover/HlLming/notes/s.png differ diff --git a/mover/HlLming/readme.md b/mover/HlLming/readme.md index ffe2a6d37..d6ae71b00 100644 --- a/mover/HlLming/readme.md +++ b/mover/HlLming/readme.md @@ -31,23 +31,23 @@ - [x] scan上的NFT截图:![Scan截图](./notes/nft.png) ## 04 Move Game -- [] game package id : -- [] deposit Coin hash: -- [] withdraw `Coin` hash: -- [] play game hash: +- [x] game package id: 0x4c72ef8941dc4e55d9514b4a3b357f02778dd9e2e7b4cf7ee100b35ccdec7640 +- [x] deposit Coin hash: DAuPRANTYTycaYXVgPRGAwXSzQEKCUj13rbCkeRnLAX +- [x] withdraw `Coin` hash: KSwtHRmUEpbroeAq2pHh3N9duWUJMJuzCFCvYUz49Di +- [x] play game hash: DRmiqKQwHDxQNMUR1AeMkGi5ZWGP8nnSn46fxgy9hMrc ## 05 Move Swap -- [] swap package id : -- [] call swap CoinA-> CoinB hash : -- [] call swap CoinB-> CoinA hash : +- [x] swap package id : 0x5e6a9eb51859738d349580f661812279cecf1f5b56856058bec29cb96cef6247 +- [x] call swap CoinA-> CoinB hash : tmKJ2QACQrRXKEViVHNfiAyiLXbNaSrjmB3tuk1DoT8 +- [x] call swap CoinB-> CoinA hash : H3kiw8XEkaSx7oVyeSwo81SkWnur3guQsFbbxnGUwYoC ## 06 Dapp-kit SDK PTB -- [] save hash : +- [x] save hash : Anndq9oE3sJBSSyepSNexSbHVWrheWBb3JZKUvwMDYxB ## 07 Move CTF Check In -- [] CLI call 截图 : ![截图](./images/你的图片地址) -- [] flag hash : +- [x] CLI call 截图 : ![截图](./notes/s.png) +- [x] flag hash : 8jkui2Ja7PSR3vvFxrQE7VY2F7x4MRZd2ZZTsNhVoW2Q ## 08 Move CTF Lets Move -- [] proof : -- [] flag hash : +- [x] proof : 9071665258e933a4b98a +- [x] flag hash : qXoetJHvCEvVTmMV4XDbju1oXyMaeph7RhPWFR2cGwm