本文转自本人微信公众号的文章,所以带有wx水印,希望大家能理解一下。后续新文会自己留存不带水印。
1.1 游戏设计
参考于三个骰子猜大小游戏
设计三个骰子参数为随机数,然后其和的值4至10称作小,11至17为大。
新建random.move,用来生成随机数。
module sicbogame::random{
use std::hash;
use std::vector;
use sui::bcs;
use sui::object;
use sui::tx_context::TxContext;
const ERR_HIGH_ARG_GREATER_THAN_LOW_ARG: u64 = 101;
fun seed(ctx: &mut TxContext): vector<u8> {
let ctx_bytes = bcs::to_bytes(ctx);
let uid = object::new(ctx);
let uid_bytes: vector<u8> = object::uid_to_bytes(&uid);
object::delete(uid);
let info: vector<u8> = vector::empty<u8>();
vector::append<u8>(&mut info, ctx_bytes);
vector::append<u8>(&mut info, uid_bytes);
let hash: vector<u8> = hash::sha3_256(info);
hash
}
fun bytes_to_u64(bytes: vector<u8>): u64 {
let value = 0u64;
let i = 0u64;
while (i < 8) {
value = value | ((*vector::borrow(&bytes, i) as u64) << ((8 * (7 - i)) as u8));
i = i + 1;
};
return value
}
/// Generate a random u64
fun rand_u64_with_seed(_seed: vector<u8>): u64 {
bytes_to_u64(_seed)
}
/// Generate a random integer range in [low, high).
fun rand_u64_range_with_seed(_seed: vector<u8>, 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
}
/// Generate a random u64
public fun rand_u64(ctx: &mut TxContext): u64 {
rand_u64_with_seed(seed(ctx))
}
/// Generate a random integer range in [low, high).
public fun rand_u64_range(low: u64, high: u64, ctx: &mut TxContext): u64 {
rand_u64_range_with_seed(seed(ctx), low, high)
}
}
然后新建sicbogame.move,来制定游戏规则。
module sicbogame::sicbogame{
use std::vector;
use sui::event;
use sui::tx_context::{ TxContext};
use std::string;
use sicbogame::random;
const ERROR_INPUT_NUM :u64 = 1;
struct Result has copy,drop {
msg: string::String
}
public entry fun create_game(input_num: u64, ctx: &mut TxContext){
assert!((input_num != 1 || input_num !=0), ERROR_INPUT_NUM);
let dice1 = random::rand_u64_range(1, 6, ctx);
let dice2 = random::rand_u64_range(1, 6, ctx);
let dice3 = random::rand_u64_range(1, 6, ctx);
let dice = dice1 + dice2 + dice3;
let resp;
if (input_num == 0) {
if (dice >= 4 && dice <= 10) {
resp = b"You Win :)";
} else {
resp = b"You Lose :(";
}
}
else if (input_num == 1) {
if (dice >= 11 && dice <= 17) {
resp = b"You Win :)";
} else {
resp = b"You Lose :(";
}
} else {
resp = b"Invalid input number";
};
event::emit(Result{msg: string::utf8(resp)});
}
#[test_only]
public fun test_game(ctx: &mut TxContext) {
let input_num = 0;
create_game(input_num,ctx);
}
}
1.2 部署合约
sui client publish --gas-budget 100000000 --skip-dependency-verification
│ ┌── │
│ │ PackageID: 0x4047ca9d7990e25abe3dea249e54eb5ed079212dd976f1ccc30700a96d01608f │
│ │ Version: 1 │
│ │ Digest: GVMBTupzMH5weX5hAuSRiWuB6wTxj9obzEdH3dLZHUPM │
│ │ Modules: random, sicbogame │
│ └──
然后猜大小,根据合约中的规则,传入0为猜小,传入1为猜大。
下面猜大,然后通过event获取结果为赢。
sui client call --package 0x4047ca9d7990e25abe3dea249e54eb5ed079212dd976f1ccc30700a96d01608f --module sicbogame --function create_game --args 1 --gas-budget 10000000
Transaction Digest: CT4xf89srjuUz2exEkuwDMXHzFibT6DX3V7XYshGPD4F
╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events │
├─────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ┌── │
│ │ EventID: CT4xf89srjuUz2exEkuwDMXHzFibT6DX3V7XYshGPD4F:0 │
│ │ PackageID: 0x4047ca9d7990e25abe3dea249e54eb5ed079212dd976f1ccc30700a96d01608f │
│ │ Transaction Module: sicbogame │
│ │ Sender: 0x772b31a5738f0ceb70d313c7f1361bb1a9fa9732f9f1c9255cb191a592cbf988 │
│ │ EventType: 0x4047ca9d7990e25abe3dea249e54eb5ed079212dd976f1ccc30700a96d01608f::sicbogame::Result │
│ │ ParsedJSON: │
│ │ ┌─────┬────────────┐ │
│ │ │ msg │ You Win :) │ │
│ │ └─────┴────────────┘ │
│ └── │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯
再猜一次大,通过event获取结果为输。
Transaction Digest: B2L7t4HibAmE1ZeLqpEv3Hvovr2tQqJomdwD8QnEPDVV
╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events │
├─────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ┌── │
│ │ EventID: B2L7t4HibAmE1ZeLqpEv3Hvovr2tQqJomdwD8QnEPDVV:0 │
│ │ PackageID: 0x4047ca9d7990e25abe3dea249e54eb5ed079212dd976f1ccc30700a96d01608f │
│ │ Transaction Module: sicbogame │
│ │ Sender: 0x772b31a5738f0ceb70d313c7f1361bb1a9fa9732f9f1c9255cb191a592cbf988 │
│ │ EventType: 0x4047ca9d7990e25abe3dea249e54eb5ed079212dd976f1ccc30700a96d01608f::sicbogame::Result │
│ │ ParsedJSON: │
│ │ ┌─────┬─────────────┐ │
│ │ │ msg │ You Lose :( │ │
│ │ └─────┴─────────────┘ │
│ └── │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯
参考链接:
伪随机数:https://github.com/chrisyy2003/ctf-writeup/blob/main/MoveCTF/simple_game/sources/random.move
Sui move_cn社交账号
telegram: https://t.me/move_cn
X(twitter): https://twitter.com/move_cn
QQ群: 79489587
微信公众号:Move中文
Sui中文开发群: https://t.me/sui_dev_cn
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!