-
Notifications
You must be signed in to change notification settings - Fork 4
/
random.move
68 lines (57 loc) · 2.22 KB
/
random.move
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// 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 ctf::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)
}
}