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
69
70
71
72
73
74
75
#![no_std]
#[cfg(not(feature = "lock_binary"))]
extern crate alloc;
#[cfg(any(feature = "lock_binary", feature = "test_tool"))]
extern crate std;
#[cfg(feature = "test_tool")]
pub mod test_tool;
pub mod locks {
include!(concat!(env!("OUT_DIR"), "/code_hashes.rs"));
#[cfg(feature = "lock_binary")]
pub mod binary {
use std::borrow::Cow;
include!(concat!(env!("OUT_DIR"), "/bundled.rs"));
const BINARIES: [&str; 2] = [
"/specs/cells/secp256k1_data",
"/specs/cells/secp256k1_keccak256_sighash_all_dual",
];
#[repr(u8)]
pub enum Binary {
Secp256k1Data = 1,
Secp256k1Keccak256SighashDual,
}
pub fn get(binary: Binary) -> Cow<'static, [u8]> {
BUNDLED_CELL
.get(BINARIES[binary as usize - 1])
.expect("should be packaged")
}
}
}
use ckb_std::dynamic_loading::{CKBDLContext, Symbol};
type VerifySecp256k1KeccakSighashAll = unsafe extern "C" fn(eth_address: *const [u8; 20]) -> i32;
const VERIFY_SECP256K1_KECCAK_SIGHASH_ALL: &[u8; 35] = b"verify_secp256k1_keccak_sighash_all";
pub struct DynLock {
verify_signhash: Symbol<VerifySecp256k1KeccakSighashAll>,
}
impl DynLock {
pub fn load<T>(context: &mut CKBDLContext<T>, code_hash: &[u8]) -> Self {
let lock = context.load(code_hash).expect("load lock lib");
let verify_signhash: Symbol<VerifySecp256k1KeccakSighashAll> = unsafe {
lock.get(VERIFY_SECP256K1_KECCAK_SIGHASH_ALL)
.expect("load sign hash fn")
};
DynLock { verify_signhash }
}
pub fn verify(&self, hash: &[u8; 20]) -> Result<(), i32> {
let verify_signhash = &self.verify_signhash;
let error_code = unsafe { verify_signhash(hash) };
if error_code != 0 {
return Err(error_code);
}
Ok(())
}
}