-
Notifications
You must be signed in to change notification settings - Fork 893
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
1,250 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { bcs, fromHex, toHex } from '@mysten/bcs'; | ||
import { sha3_256 } from '@noble/hashes/sha3'; | ||
|
||
// Address type for 32-byte addresses | ||
const Address = bcs.bytes(32).transform({ | ||
input: (val: string) => fromHex(val), | ||
output: (val) => toHex(val), | ||
}); | ||
|
||
// UID type for 32-byte unique identifiers | ||
const UID = bcs.fixedArray(32, bcs.u8()).transform({ | ||
input: (id: string) => fromHex(id), | ||
output: (id) => toHex(Uint8Array.from(id)), | ||
}); | ||
|
||
// Test sender address | ||
const sender = '0x77083d27beec05358aff1356c1826fc582ae381440c028646b817705aabca3a8'; | ||
const senderBytes = Address.serialize(sender).toBytes(); | ||
|
||
// Challenge struct definition | ||
const ChallengeStruct = bcs.struct('Challenge', { | ||
id: UID, | ||
str: bcs.string(), | ||
difficulity: bcs.u64(), | ||
ture_num: bcs.u64(), | ||
}); | ||
|
||
// Test challenge data | ||
const challengeBytes = ChallengeStruct.serialize({ | ||
id: '0x19e76ca504c5a5fa5e214a45fca6c058171ba333f6da897b82731094504d5ab9', | ||
str: "]c:_}|)[iB'G*$p1E\"$", | ||
difficulity: 3, | ||
ture_num: 100, | ||
}).toBytes(); | ||
|
||
/** | ||
* Calculates proof of work by finding a number that results in a hash with specific properties | ||
* @param maxAttempts Maximum number of attempts before giving up | ||
* @returns The proof number if found, null otherwise | ||
*/ | ||
function calculateProof(maxAttempts = 10000000): number | null { | ||
const targetPrefixSum = 0; | ||
const prefixLength = 3; | ||
|
||
for (let attempts = 1; attempts <= maxAttempts; attempts++) { | ||
// Generate random proof between 0 and 100M | ||
const proof = Math.floor(Math.random() * 100000000); | ||
|
||
if (attempts % 1000 === 0) { | ||
console.log(`Attempt ${attempts}: ${proof}`); | ||
} | ||
|
||
const proofBytes = bcs.u64().serialize(proof).toBytes(); | ||
|
||
// Combine all components for hashing | ||
const combined = new Uint8Array([...proofBytes, ...senderBytes, ...challengeBytes]); | ||
const hash = sha3_256(combined); | ||
|
||
// Calculate prefix sum of first N bytes | ||
const prefix_sum = hash | ||
.slice(0, prefixLength) | ||
.reduce((sum, byte) => sum + byte, 0); | ||
|
||
if (prefix_sum === targetPrefixSum) { | ||
console.log(`Success! Found proof after ${attempts} attempts: ${proof}`); | ||
console.log(`Proof bytes: [${proofBytes.toString()}]`); | ||
return proof; | ||
} | ||
} | ||
|
||
console.error(`Failed to find proof after ${maxAttempts} attempts`); | ||
return null; | ||
} | ||
|
||
// Execute proof calculation | ||
calculateProof(); | ||
|
||
// Success! Found proof after 7158758 attempts: 5860720 | ||
// Proof bytes: [112,109,89,0,0,0,0,0] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { bcs, fromBase64 } from "@mysten/bcs"; | ||
import { getFullnodeUrl, SuiClient } from "@mysten/sui/dist/cjs/client"; | ||
import { Transaction } from "@mysten/sui/transactions"; | ||
import { execSync } from "child_process"; | ||
import { readFileSync } from "fs"; | ||
import { homedir } from "os"; | ||
import path from "path"; | ||
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519"; | ||
|
||
export const getAddressByAlias = (alias: string): string => { | ||
const str = execSync(`sui client switch --address ${alias}`, { | ||
encoding: "utf8", | ||
}).trim(); | ||
|
||
const regex = /Active address switched to (\S+)/; | ||
const match = str.match(regex); | ||
|
||
return match ? match[1] : ""; | ||
}; | ||
|
||
export const getSigner = (alias: string) => { | ||
const sender = getAddressByAlias(alias); | ||
|
||
const keystore = JSON.parse( | ||
readFileSync( | ||
path.join(homedir(), ".sui", "sui_config", "sui.keystore"), | ||
"utf8" | ||
) | ||
); | ||
|
||
for (const priv of keystore) { | ||
const raw = fromBase64(priv); | ||
if (raw[0] !== 0) { | ||
continue; | ||
} | ||
|
||
const pair = Ed25519Keypair.fromSecretKey(raw.slice(1)); | ||
if (pair.getPublicKey().toSuiAddress() === sender) { | ||
return pair; | ||
} | ||
} | ||
|
||
throw new Error(`keypair not found for sender: ${sender}`); | ||
}; | ||
|
||
async function call() { | ||
const rpcUrl = getFullnodeUrl("testnet"); | ||
const client = new SuiClient({ url: rpcUrl }); | ||
|
||
const pkgId = | ||
"0x097a3833b6b5c62ca6ad10f0509dffdadff7ce31e1d86e63e884a14860cedc0f"; | ||
const moduleName = "lets_move"; | ||
const funcName = "get_flag"; | ||
|
||
const tx = new Transaction(); | ||
|
||
tx.moveCall({ | ||
target: `${pkgId}::${moduleName}::${funcName}`, | ||
|
||
arguments: [ | ||
tx.pure(bcs.vector(bcs.u8()).serialize([112, 109, 89, 0, 0, 0, 0, 0])), | ||
tx.pure.string("JasonRUAN"), | ||
tx.object( | ||
"0x19e76ca504c5a5fa5e214a45fca6c058171ba333f6da897b82731094504d5ab9" | ||
), | ||
tx.object("0x8"), | ||
], | ||
}); | ||
|
||
const signer = getSigner("JasonRUAN"); | ||
const result = await client.signAndExecuteTransaction({ | ||
signer, | ||
transaction: tx, | ||
}); | ||
return result; | ||
} | ||
|
||
call().then(console.log).catch(console.error); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# @generated by Move, please check-in and do not edit manually. | ||
|
||
[move] | ||
version = 3 | ||
manifest_digest = "786B91A5B97E30CFE4109DB806C7FDAA208AD34906C77AB899770D4D0AEB5DB1" | ||
deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" | ||
dependencies = [ | ||
{ id = "Sui", name = "Sui" }, | ||
] | ||
|
||
[[move.package]] | ||
id = "MoveStdlib" | ||
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/move-stdlib" } | ||
|
||
[[move.package]] | ||
id = "Sui" | ||
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/sui-framework" } | ||
|
||
dependencies = [ | ||
{ id = "MoveStdlib", name = "MoveStdlib" }, | ||
] | ||
|
||
[move.toolchain-version] | ||
compiler-version = "1.39.0" | ||
edition = "2024.beta" | ||
flavor = "sui" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
[package] | ||
name = "lets_move" | ||
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/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] | ||
lets_move = "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" | ||
|
86 changes: 86 additions & 0 deletions
86
mover/JasonRUAN/code/task8/contract/lets_move/sources/lets_move.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
module lets_move::lets_move { | ||
use std::ascii::{String, string}; | ||
use std::hash; | ||
use sui::event; | ||
use sui::bcs; | ||
use sui::random; | ||
use sui::random::Random; | ||
use sui::transfer::share_object; | ||
|
||
const EPROOF: u64 = 0; | ||
|
||
public struct Flag has copy, drop { | ||
sender: address, | ||
flag: bool, | ||
ture_num: u64, | ||
github_id: String | ||
} | ||
|
||
public struct Challenge has key { | ||
id: UID, | ||
str: String, | ||
difficulity: u64, | ||
ture_num: u64 | ||
} | ||
|
||
fun init(ctx: &mut TxContext) { | ||
let flag_str = Challenge { | ||
id: object::new(ctx), | ||
str: string(b"LetsMoveCTF"), | ||
difficulity: 3, | ||
ture_num: 0, | ||
}; | ||
share_object(flag_str); | ||
} | ||
|
||
|
||
entry fun get_flag( | ||
proof: vector<u8>, | ||
github_id: String, | ||
challenge: &mut Challenge, | ||
rand: &Random, | ||
ctx: &mut TxContext | ||
) { | ||
let mut full_proof: vector<u8> = vector::empty<u8>(); | ||
vector::append<u8>(&mut full_proof, proof); | ||
vector::append<u8>(&mut full_proof, tx_context::sender(ctx).to_bytes()); | ||
vector::append<u8>(&mut full_proof, bcs::to_bytes(challenge)); | ||
|
||
let hash: vector<u8> = hash::sha3_256(full_proof); | ||
|
||
let mut prefix_sum: u32 = 0; | ||
let mut i: u64 = 0; | ||
while (i < challenge.difficulity) { | ||
prefix_sum = prefix_sum + (*vector::borrow(&hash, i) as u32); | ||
i = i + 1; | ||
}; | ||
|
||
assert!(prefix_sum == 0, EPROOF); | ||
|
||
challenge.str = getRandomString(rand, ctx); | ||
challenge.ture_num = challenge.ture_num + 1; | ||
|
||
event::emit(Flag { | ||
sender: tx_context::sender(ctx), | ||
flag: true, | ||
ture_num: challenge.ture_num, | ||
github_id | ||
}); | ||
} | ||
|
||
|
||
fun getRandomString(rand: &Random, ctx: &mut TxContext): String { | ||
let mut gen = random::new_generator(rand, ctx); | ||
|
||
let mut str_len = random::generate_u8_in_range(&mut gen, 4, 30); | ||
|
||
let mut rand: vector<u8> = b""; | ||
while (str_len != 0) { | ||
let rand_num = random::generate_u8_in_range(&mut gen, 34, 126); | ||
vector::push_back(&mut rand, rand_num); | ||
str_len = str_len - 1; | ||
}; | ||
|
||
string(rand) | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
mover/JasonRUAN/code/task8/contract/lets_move/tests/lets_move_tests.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
#[test_only] | ||
module lets_move::lets_move_tests; | ||
// uncomment this line to import the module | ||
// use lets_move::lets_move; | ||
const ENotImplemented: u64 = 0; | ||
#[test] | ||
fun test_lets_move() { | ||
// pass | ||
} | ||
#[test, expected_failure(abort_code = ::lets_move::lets_move_tests::ENotImplemented)] | ||
fun test_lets_move_fail() { | ||
abort ENotImplemented | ||
} | ||
*/ |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.