-
Notifications
You must be signed in to change notification settings - Fork 0
/
code-time-lock.rs
65 lines (52 loc) · 1.67 KB
/
code-time-lock.rs
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
// src: https://github.com/Hanssen0/ckb-script-time-lock
use core::result::Result;
use ckb_std::{
ckb_constants::Source,
ckb_types::{bytes::Bytes, prelude::*},
debug,
dynamic_loading_c_impl::CKBDLContext,
high_level::{load_header, load_script, QueryIter},
};
use crate::error::Error;
use ckb_lib_secp256k1::LibSecp256k1;
pub fn main() -> Result<(), Error> {
let script = load_script()?;
let args: Bytes = script.args().unpack();
if args.len() != 28 {
return Err(Error::Encoding);
}
let pubkey = args.slice(0..20);
let time_limit = args.slice(20..28);
if !has_passed_time_limit(time_limit) {
return Err(Error::TimeLimitNotReached);
}
// create a DL context with 128K buffer size
let mut context = unsafe { CKBDLContext::<[u8; 128 * 1024]>::new() };
let lib = LibSecp256k1::load(&mut context);
test_validate_blake2b_sighash_all(&lib, &pubkey)
}
fn has_passed_time_limit(time_limit: Bytes) -> bool {
for header in QueryIter::new(load_header, Source::HeaderDep) {
let timestamp = header.raw().timestamp().unpack().to_be_bytes();
if time_limit.le(×tamp) {
return true;
}
}
false
}
fn test_validate_blake2b_sighash_all(
lib: &LibSecp256k1,
expected_pubkey_hash: &[u8],
) -> Result<(), Error> {
let mut pubkey_hash = [0u8; 20];
lib.validate_blake2b_sighash_all(&mut pubkey_hash)
.map_err(|_err_code| {
debug!("secp256k1 error {}", _err_code);
Error::Secp256k1
})?;
// compare with expected pubkey_hash
if &pubkey_hash[..] != expected_pubkey_hash {
return Err(Error::WrongPubkey);
}
Ok(())
}