Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

完成task4 #1944

Merged
merged 3 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion mover/ctianming/co-learn-2411/images/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,7 @@ task3_image
b站关注

![alt text](image.png)
第四篇笔记分享
第四篇笔记分享

![alt text](image.png)
第五篇笔记分享
85 changes: 85 additions & 0 deletions mover/ctianming/co-learn-2411/project/move_game/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Sui 项目 Makefile
# 项目路径设置
MOVE_PATH := .
BUILD_PATH := $(MOVE_PATH)/build
SUI_CLI := sui

# 默认网络为 devnet,可通过 `make <target> NETWORK=<network>` 来覆盖
NETWORK := $(or $(NETWORK), mainnet)
GAS_BUDGET := $(or $(GAS_BUDGET), 2000000)

# 默认目标
all: build

# 切换网络
switch:
@echo "Switching to network: $(NETWORK)..."
@if [ -z "$(NETWORK)" ]; then \
echo "Error: No network specified. Please set NETWORK."; \
exit 1; \
fi
$(SUI_CLI) client switch --env $(NETWORK)
@echo "Switched to network: $(NETWORK)"
export NETWORK=$(NETWORK)
# 编译 Move 代码
build:
@echo "Building the Sui Move package..."
@if [ -n "$(NETWORK)" ] && [ "$(NETWORK)" != "devnet" ]; then \
echo "Switching to network: $(NETWORK)"; \
$(SUI_CLI) client switch --env $(NETWORK); \
elif [ "$(NETWORK)" = "devnet" ]; then \
echo "Using the current network $(NETWORK)"; \
fi
$(SUI_CLI) move build --path $(MOVE_PATH)

# 运行测试
test:
@echo "Running tests on Sui Move package..."
@if [ -n "$(NETWORK)" ] && [ "$(NETWORK)" != "devnet" ]; then \
echo "Switching to network: $(NETWORK)"; \
$(SUI_CLI) client switch --env $(NETWORK); \
elif [ "$(NETWORK)" = "devnet" ]; then \
echo "Using the current network $(NETWORK)"; \
fi
$(SUI_CLI) move test --path $(MOVE_PATH)

# 发布合约到 Devnet
publish:
@echo "Publishing the package to $(SUI_NETWORK)..."
@if [ -n "$(NETWORK)" ] && [ "$(NETWORK)" != "devnet" ]; then \
echo "Switching to network: $(NETWORK)"; \
$(SUI_CLI) client switch --env $(NETWORK); \
elif [ "$(NETWORK)" = "devnet" ]; then \
echo "Using the current network $(NETWORK)"; \
fi
$(SUI_CLI) client publish --gas-budget $(GAS_BUDGET)

# 清理生成的文件
clean:
@echo "Cleaning up the build directory..."
rm -rf $(BUILD_PATH)

# 此命令仅适用于使用 brew 下载 sui 的用户
update:
@echo "Updating brew and sui"
brew update
brew upgrade sui

# 查看合约状态
# 这里我只添加了三个命令,可以根据自己的需要增减
status:
@echo "Checking the status of the Sui project..."
$(SUI_CLI) client active-env
$(SUI_CLI) client active-address
$(SUI_CLI) client balance

# 帮助信息
help:
@echo "使用 Makefile 中的以下命令进行常见操作:"
@echo " make build - 编译 Move 包"
@echo " make test - 测试 Move 包"
@echo " make publish - 发布合约到网络"
@echo " make clean - 清理生成的文件"
@echo " make status - 查看合约状态"

.PHONY: all build test publish clean status help
52 changes: 52 additions & 0 deletions mover/ctianming/co-learn-2411/project/move_game/Move.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# @generated by Move, please check-in and do not edit manually.

[move]
version = 3
manifest_digest = "83DFB5479D28E523C7E5913B7491473354EFCE7A79E0E0E6D6729E1D83FF9489"
deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3"
dependencies = [
{ id = "Sui", name = "Sui" },
{ id = "move_coin", name = "move_coin" },
{ id = "move_nft", name = "move_nft" },
]

[[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 = "move_coin"
source = { local = "/home/amyseer/sui/letsmove/mover/ctianming/co-learn-2411/project/move_coin" }

dependencies = [
{ id = "Sui", name = "Sui" },
]

[[move.package]]
id = "move_nft"
source = { local = "/home/amyseer/sui/letsmove/mover/ctianming/co-learn-2411/project/move_nft" }

dependencies = [
{ id = "Sui", name = "Sui" },
]

[move.toolchain-version]
compiler-version = "1.37.3"
edition = "2024.beta"
flavor = "sui"

[env]

[env.mainnet]
chain-id = "35834a8a"
original-published-id = "0xed3a81bb858d2b3807b2ad29597c637b7972dacd60a5120b9a0e92f9c0164087"
latest-published-id = "0xed3a81bb858d2b3807b2ad29597c637b7972dacd60a5120b9a0e92f9c0164087"
published-version = "1"
38 changes: 38 additions & 0 deletions mover/ctianming/co-learn-2411/project/move_game/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[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 ([email protected])", "John Snow ([email protected])"]

[dependencies]
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "framework/mainnet" }
move_coin = { local = "/home/amyseer/sui/letsmove/mover/ctianming/co-learn-2411/project/move_coin/" }
move_nft = { local = "/home/amyseer/sui/letsmove/mover/ctianming/co-learn-2411/project/move_nft/" }

# 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"
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
module move_game::guess_game {
/// 所有,或者一无所有!
use sui::tx_context::{sender};
use sui::event::emit;
use move_coin::faucet_coin::{Self, FAUCET_COIN};
use move_nft::move_nft::{Self};
use sui::coin::{Self,Coin,TreasuryCap};
use sui::balance::{Self, Balance};
use sui::address;
use sui::table::{Self, Table};
use sui::bcs;

const EInvalid:u64 = 0;
const EInputNotEnough:u64 = 1;
const ECurrencyNotEnough:u64 = 2;
const EHaveWon:u64 = 4;
const ENotUser:u64 = 5;

/// 定义游戏
public struct Game has key, store {
id: UID,
secret_number: Option<u32>,
attempts: u32,
over: bool,
winner: address,
cost_per_round: u64,
pool: u64,
game_pool: Balance<FAUCET_COIN>,
users: Table<address, USER>,
}

/// 定义游戏事件
public enum GuessEvent has copy, drop, store {
TooSmall,
TooBig,
Correct,
}

public struct USER has store{
balance: u64,
}

public struct AdminCap has key{id:UID}

/// 初始化游戏
fun init(ctx: &mut TxContext){
let game = Game {
id: object::new(ctx),
secret_number: option::none(),
attempts: 0,
over: false,
winner: address::from_u256(0),
cost_per_round: 10, //define the cost per round is 10 faucet_coin
pool: 0,
game_pool: balance::zero<FAUCET_COIN>(),
users: table::new<address, USER>(ctx),
};
transfer::share_object(game);
transfer::transfer(AdminCap{id:object::new(ctx)},sender(ctx));
}

//get random number
// public entry fun get_random_number(_: &AdminCap, game: &mut Game, r: &Random, ctx: &mut TxContext) {
// let mut generator=random::new_generator(r,ctx);
// let random_value=random::generate_u8_in_range(&mut generator,1,101);
// game.secret_number = random_value as u32;
// }
public entry fun get_random_number(_: &AdminCap, game: &mut Game, magic_number: u64, ctx: &mut TxContext) {
let sender_address = tx_context::sender(ctx);
let timestamp = tx_context::epoch_timestamp_ms(ctx);
let address_bytes = address::to_bytes(sender_address);
let timestamp_bytes = bcs::to_bytes(&timestamp);
let magic_number_bytes = bcs::to_bytes(&magic_number);
let mut hash_input = address_bytes;
vector::append(&mut hash_input, timestamp_bytes);
vector::append(&mut hash_input, magic_number_bytes);
let hash_output = sui::hash::blake2b256(&hash_input);
// 取哈希值的第一个字节并转换为随机数 [1, 100]
let random_byte = *vector::borrow(&hash_output, 0); // 解引用 &u8
let random_value = (random_byte as u32) % 100 + 1;
game.secret_number = option::some(random_value);
}

//get faucet_coin
public entry fun get_faucet_coin(
treasury_cap:&mut TreasuryCap<FAUCET_COIN>,
amount: u64,
ctx: &mut TxContext) {
faucet_coin::mint(treasury_cap,amount,tx_context::sender(ctx),ctx);
}

//deposit Coin
public entry fun deposit(game: &mut Game, input: Coin<FAUCET_COIN>, amount: u64, ctx: &mut TxContext) {
let caller = tx_context::sender(ctx);
// get the input value and assert
let input_value = coin::value(&input);
assert!(input_value >= amount, EInputNotEnough);
// transection the input value to Balance
let mut input_balance = coin::into_balance(input);
// if input valye much tran amount, change the excess
if (input_value > amount) {
balance::join(
&mut game.game_pool,
balance::split(&mut input_balance, amount),
);
let change = coin::from_balance(input_balance, ctx);
transfer::public_transfer(change, caller);
} else {
balance::join(&mut game.game_pool, input_balance);
};
// check if user in table `users`
if (!table::contains(&game.users, caller)) {
// insert new user, and set its balance
table::add(&mut game.users, caller, USER { balance: amount });
} else {
// user is valid,update its balance
let user = table::borrow_mut(&mut game.users, caller);
user.balance = user.balance + amount;
}
}

//withdraw Coin
public entry fun withdraw(_: &AdminCap, game: &mut Game, amount: u64, ctx: &mut TxContext) {
let output_balance = balance::split(&mut game.game_pool, amount);
let output = coin::from_balance(output_balance, ctx);
transfer::public_transfer(output, sender(ctx));
game.pool = game.pool - amount;
}

//restart
public entry fun restart(_: &AdminCap, game: &mut Game) {
game.secret_number = option::none();
game.attempts = 0;
game.over = false;
game.winner = address::from_u256(0);
}

/// user guess
public entry fun make_guess(game: &mut Game, coin: Coin<FAUCET_COIN>, guess: u32, ctx: &mut TxContext) {
game.attempts = game.attempts + 1;
let caller = tx_context::sender(ctx);
// base check
assert!(game.secret_number != option::none(), EInvalid);
assert!(game.over != true, EHaveWon);
assert!(game.winner == address::from_u256(0), EHaveWon);
assert!(table::contains(&game.users, caller), ENotUser);
assert!(guess >= 1 && guess <= 100, EInvalid);
// check the balance
let user = table::borrow_mut(&mut game.users, caller);
assert!(user.balance >= game.cost_per_round, ECurrencyNotEnough); // currency not enough
user.balance = user.balance - game.cost_per_round; // deduct the cost
// input the balance into pool
let input_balance = coin::into_balance(coin);
balance::join(&mut game.game_pool, input_balance);
game.pool = game.pool + game.cost_per_round;
// compare guess with secret number
let secret_number = option::borrow(&game.secret_number);
if (guess < *secret_number) {
emit(GuessEvent::TooSmall); // too small
} else if (guess > *secret_number) {
emit(GuessEvent::TooBig); // too big
} else {
// guess correct
emit(GuessEvent::Correct);
// game over
game.over = true;
game.winner = caller;
// get reward
// let reward_balance = balance::split(&mut game.game_pool, user.balance);
// let reward = coin::from_balance(reward_balance, ctx);
// NOTHING, OR EVERYTHING!!!
let reward_balance = balance::split(&mut game.game_pool, 0);
let reward = coin::from_balance(reward_balance, ctx);
transfer::public_transfer(reward, caller);
// give a NFT to winner
move_nft::mint(b"TruE", b"Bless Alysia! from ctianming≥v≤", b"https://avatars.githubusercontent.com/u/107739505?v=4", caller, ctx);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
#[test_only]
module move_game::move_game_tests;
// uncomment this line to import the module
// use move_game::move_game;

const ENotImplemented: u64 = 0;

#[test]
fun test_move_game() {
// pass
}

#[test, expected_failure(abort_code = ::move_game::move_game_tests::ENotImplemented)]
fun test_move_game_fail() {
abort ENotImplemented
}
*/
Loading