127 lines
3.6 KiB
Rust
127 lines
3.6 KiB
Rust
// lib.rs
|
||
//
|
||
// 此部分代码主要负责Rust-C两侧的数据内存结构转换,提供了C侧的函数接口。注意命名规范:
|
||
// 在C侧使用时,凡是函数名带有 '_cwallet'的,调用过之后都必须用'free_cwallet'释放内存,
|
||
// 否则导致内存泄漏
|
||
//
|
||
|
||
use std::ffi::{CStr, CString};
|
||
use std::os::raw::c_char;
|
||
|
||
mod wallet;
|
||
|
||
use wallet_impl::Wallet;
|
||
|
||
use crate::wallet::*;
|
||
|
||
// #[cfg(target_os = "android")]
|
||
// mod android;
|
||
|
||
#[repr(C)]
|
||
pub struct CWallet {
|
||
pub public_key: *mut c_char,
|
||
pub private_key: *mut c_char,
|
||
pub public_addr: *mut c_char,
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub unsafe extern "C" fn generate_cwallet() -> CWallet {
|
||
println!("generating wallet");
|
||
let (secret_key, pub_key) = wallet_impl::generate_keypair();
|
||
|
||
// println!("secret key: {}", &secret_key.to_string());
|
||
// println!("public key: {}", &pub_key.to_string());
|
||
|
||
//let pub_address = eth_wallet::public_key_address(&pub_key);
|
||
//println!("public address: {:?}", pub_address);
|
||
|
||
let rust_wallet = wallet_impl::Wallet::new(&secret_key, &pub_key);
|
||
println!("rust_wallet: {:?}", &rust_wallet);
|
||
convert_to_cwallet(rust_wallet)
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub unsafe extern "C" fn free_cwallet(cw: CWallet) {
|
||
drop(CString::from_raw(cw.public_key));
|
||
drop(CString::from_raw(cw.private_key));
|
||
drop(CString::from_raw(cw.public_addr));
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub unsafe extern "C" fn save_wallet(cw: &CWallet) {
|
||
let rwallet = convert_to_rwallet(cw);
|
||
wallet_impl::Wallet::save_keys(&rwallet, "wallet.json").unwrap();
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub unsafe extern "C" fn fetch_cwallet() -> CWallet {
|
||
match wallet_impl::Wallet::retrieve_keys("wallet.json") {
|
||
Err(_) => {
|
||
let wallet = wallet_impl::Wallet {
|
||
secret_key: "".to_string(),
|
||
public_key: "".to_string(),
|
||
public_address: "".to_string(),
|
||
};
|
||
return convert_to_cwallet(wallet);
|
||
}
|
||
Ok(w) => return convert_to_cwallet(w),
|
||
};
|
||
}
|
||
#[no_mangle]
|
||
pub unsafe extern "C" fn sign() {
|
||
match wallet_impl::Wallet::retrieve_keys("wallet.json") {
|
||
Err(_) => {
|
||
println!("error sign");
|
||
}
|
||
Ok(w) => {
|
||
match w.sign("111") {
|
||
Err(err) => {
|
||
println!("error sign: {:?}", err);
|
||
}
|
||
Ok(sig) => {
|
||
println!("sig result: {:?}", sig);
|
||
}
|
||
}
|
||
|
||
}
|
||
};
|
||
}
|
||
|
||
unsafe fn convert_to_cwallet(rwallet: Wallet) -> CWallet {
|
||
// 转换Rust字符串数据为C的字符串并移交ownership
|
||
let pubkey = CString::new(rwallet.public_key).unwrap();
|
||
let c_pubkey: *mut c_char = pubkey.into_raw();
|
||
let seckey = CString::new(rwallet.secret_key).unwrap();
|
||
let c_seckey: *mut c_char = seckey.into_raw();
|
||
let pubaddr = CString::new(rwallet.public_address).unwrap();
|
||
let c_pubaddr: *mut c_char = pubaddr.into_raw();
|
||
|
||
//println!("crypto wallet address: {}", CStr::from_ptr(c_pubaddr).to_str().unwrap());
|
||
|
||
let cw = CWallet {
|
||
public_key: c_pubkey,
|
||
private_key: c_seckey,
|
||
public_addr: c_pubaddr,
|
||
};
|
||
|
||
//println!("crypto_wallet addr: {}", CStr::from_ptr(cw.public_addr).to_str().unwrap());
|
||
|
||
cw
|
||
}
|
||
|
||
unsafe fn convert_to_rwallet(cwallet: &CWallet) -> Wallet {
|
||
let a = CStr::from_ptr(cwallet.public_addr);
|
||
let pa = a.to_str().unwrap();
|
||
|
||
let pk = CStr::from_ptr(cwallet.public_key);
|
||
let ppk = pk.to_str().unwrap();
|
||
|
||
let sk = CStr::from_ptr(cwallet.private_key);
|
||
let psk = sk.to_str().unwrap();
|
||
Wallet {
|
||
secret_key: psk.to_string(),
|
||
public_key: ppk.to_string(),
|
||
public_address: pa.to_string(),
|
||
}
|
||
}
|