From 880d19ce33aa9f06ee10689a982a3d31256e748c Mon Sep 17 00:00:00 2001 From: cebgcontract <99630598+cebgcontract@users.noreply.github.com> Date: Sun, 23 Oct 2022 10:11:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=AD=BE=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/test.rs | 63 +++++++++++++++++++---------- src/lib.rs | 83 ++++++++++++++++++++++++++++++--------- src/wallet/wallet_impl.rs | 15 ++----- 3 files changed, 110 insertions(+), 51 deletions(-) diff --git a/examples/test.rs b/examples/test.rs index a453890..3c92ef6 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -4,17 +4,22 @@ // 测试钱包在C侧调用接口存储和重新读出钱包密钥 // -use std::ffi::CStr; +use std::ffi::{CStr, CString}; use std::os::raw::c_char; -//use rustylib::gen::{CWallet}; -use rustwallet::{new_wallet, get_address, restore_wallet, free_cwallet, CWallet}; +use rustwallet::{new_wallet, get_address, restore_wallet, free_cwallet, sign, CWallet}; macro_rules! print_cchar{ + ($p1:expr) => ( + let s = CStr::from_ptr($p1); + let ps = s.to_str().unwrap(); + println!("{}=> {}", + stringify!($p1), + ps) + ); ($p1:expr, $p2:expr) => ( let s = CStr::from_ptr($p2); let ps = s.to_str().unwrap(); - println!(">>>>>>>>>>>>>>macro_rules print_cchar"); - println!("{:?} {:?}", + println!("{}{}", $p1, ps) ) @@ -30,20 +35,44 @@ macro_rules! cchar_to_str{ } } +macro_rules! str_to_cchar { + ($p1:expr) => { + { + let msgkey = CString::new($p1).unwrap(); + let c_msgkey: *mut c_char = msgkey.into_raw(); + c_msgkey + } + }; +} + fn main() { unsafe { let msg = "111"; - let cstr = std::ffi::CString::new(msg).unwrap(); - let wallet: CWallet = new_wallet(cstr.into_raw()); + let wallet: CWallet = new_wallet(str_to_cchar!(msg)); println!("---- generated a wallet to be used on C-side ----"); print_wallet(&wallet); - let address = get_address(wallet); - let address_str = cchar_to_str!(address); - println!("address: {}", address_str); + let address = get_address(&wallet); + print_cchar!(address); + // let address_str = cchar_to_str!(address); + // println!("address: {}", address_str); let key0 = "3da2dfc54de71230f639f37de61d8f8c4699f75e783dc54353146a4b73250366"; let key1 = "a1a3ed90e41a37096f07957b9888ffa7a74406f3a3e8c77686d92f2ba7c22d58"; let key2 = "27216cbe70021d5d1d018da5ab548b8b45dee4fd9ec0b33ab1dd264cf2ff249f"; + let tmp_cwallet = CWallet{ + msg_key: str_to_cchar!(msg), + master_key: str_to_cchar!(key0), + second_key: str_to_cchar!(""), + backup_key: str_to_cchar!(key2) + }; + let address2 = get_address(&tmp_cwallet); + print_cchar!(address2); + let tmp_cwallet2 = restore_wallet(&tmp_cwallet); + let address3 = get_address(&tmp_cwallet2); + print_cchar!(address3); + let sign = sign(&tmp_cwallet2,str_to_cchar!("111")); + print_cchar!(sign); + // print_wallet(&tmp_cwallet2); // println!("---- saving the wallet to wallet.json ----"); // save_wallet(&wallet); // println!("---- saved! ----"); @@ -62,16 +91,8 @@ fn main() { } unsafe fn print_wallet(cwallet: &CWallet) { - let pmsg = cchar_to_str!(cwallet.msg_key); - println!("msg=> {}", pmsg); print_cchar!("msg=> ", cwallet.msg_key); - - let pm = cchar_to_str!(cwallet.master_key); - println!("master key=> {}", pm); - - let ps = cchar_to_str!(cwallet.second_key); - println!("second key=> {}", ps); - - let pb = cchar_to_str!(cwallet.backup_key); - println!("backup key=> {}", pb); + print_cchar!("master key=> ", cwallet.master_key); + print_cchar!("second key=> ", cwallet.second_key); + print_cchar!("backup key=> ", cwallet.backup_key); } diff --git a/src/lib.rs b/src/lib.rs index ff80429..b73c567 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ use std::os::raw::c_char; mod wallet; +use secp256k1::schnorrsig::Signature; use wallet_impl::Wallet; use crate::wallet::*; @@ -26,6 +27,41 @@ macro_rules! cchar_to_str{ } } +macro_rules! cchar_to_string{ + ($p1:expr) => { + { + let s = CStr::from_ptr($p1); + let ps = s.to_str().unwrap(); + ps.to_string() + } + } +} + +macro_rules! cchar_to_ostring{ + ($p1:expr) => { + { + let s = CStr::from_ptr($p1); + let pb = s.to_str().unwrap(); + let result = if pb.is_empty() { + None + } else { + Some(pb.to_string()) + }; + result + } + } +} + +macro_rules! str_to_cchar { + ($p1:expr) => { + { + let msgkey = CString::new($p1).unwrap(); + let c_msgkey: *mut c_char = msgkey.into_raw(); + c_msgkey + } + }; +} + macro_rules! ostr_to_cchar{ ($p1:expr) => { { @@ -59,10 +95,9 @@ pub unsafe extern "C" fn new_wallet(msg: *const c_char) -> CWallet { } #[no_mangle] -pub unsafe extern "C" fn restore_wallet(msg: *const c_char) -> CWallet { - println!("generating wallet"); - let str = cchar_to_str!(msg); - let rust_wallet = wallet_impl::Wallet::new(str); +pub unsafe extern "C" fn restore_wallet(cw: &CWallet) -> CWallet { + println!("restore wallet"); + let rust_wallet = convert_to_rwallet(cw); println!("rust_wallet: {:?}", &rust_wallet); convert_to_cwallet(rust_wallet) } @@ -76,8 +111,8 @@ pub unsafe extern "C" fn free_cwallet(cw: CWallet) { } #[no_mangle] -pub unsafe extern "C" fn get_address(cw: CWallet) -> *mut c_char{ - let rwallet = convert_to_rwallet(&cw); +pub unsafe extern "C" fn get_address(cw: &CWallet) -> *mut c_char{ + let rwallet = convert_to_rwallet(cw); println!("rwallet: {:?}", rwallet); let address = rwallet.get_address(); let address_str = format!("{:?}", address); @@ -85,12 +120,24 @@ pub unsafe extern "C" fn get_address(cw: CWallet) -> *mut c_char{ c_address.into_raw() } +#[no_mangle] +pub unsafe extern "C" fn sign(cw: &CWallet, msg: *const c_char) -> *mut c_char{ + let rwallet = convert_to_rwallet(cw); + println!("rwallet: {:?}", rwallet); + let msg_str = cchar_to_str!(msg); + let signature = rwallet.sign(msg_str); + let r = match signature { + Ok(v) => v, + Err(err) => panic!("Problem sign: {:?}", err), + }; + str_to_cchar!(r) +} + + unsafe fn convert_to_cwallet(rwallet: Wallet) -> CWallet { // 转换Rust字符串数据为C的字符串并移交ownership - let msgkey = CString::new(rwallet.msg_key).unwrap(); - let c_msgkey: *mut c_char = msgkey.into_raw(); - let masterkey = CString::new(rwallet.master_key).unwrap(); - let c_masterkey: *mut c_char = masterkey.into_raw(); + let c_msgkey: *mut c_char = str_to_cchar!(rwallet.msg_key); + let c_masterkey: *mut c_char = str_to_cchar!(rwallet.master_key); let c_secondkey = ostr_to_cchar!(rwallet.second_key); let c_backupkey = ostr_to_cchar!(rwallet.backup_key); @@ -104,14 +151,14 @@ unsafe fn convert_to_cwallet(rwallet: Wallet) -> CWallet { } unsafe fn convert_to_rwallet(cwallet: &CWallet) -> Wallet { - let pmsg = cchar_to_str!(cwallet.msg_key); - let pm = cchar_to_str!(cwallet.master_key); - let ps = cchar_to_str!(cwallet.second_key); - let pb = cchar_to_str!(cwallet.backup_key); + let pmsg = cchar_to_string!(cwallet.msg_key); + let pm = cchar_to_string!(cwallet.master_key); + let second_key = cchar_to_ostring!(cwallet.second_key); + let backup_key = cchar_to_ostring!(cwallet.backup_key); Wallet { - msg_key: pmsg.to_string(), - master_key: pm.to_string(), - second_key: Some(ps.to_string()), - backup_key: Some(pb.to_string()) + msg_key: pmsg, + master_key: pm, + second_key: second_key, + backup_key: backup_key } } diff --git a/src/wallet/wallet_impl.rs b/src/wallet/wallet_impl.rs index e852158..8b65dad 100644 --- a/src/wallet/wallet_impl.rs +++ b/src/wallet/wallet_impl.rs @@ -173,16 +173,7 @@ impl Wallet { public_key_address(&public_key) } - // pub fn retrieve_keys(file_path: &str) -> Result { - // let file = OpenOptions::new().read(true).open(file_path)?; - // let buf_reader = BufReader::new(file); - // let wallet: Wallet = serde_json::from_reader(buf_reader)?;; - // let public_key = get_public_key(&wallet.secret_key); - // println!("public key from secret: {:?}", public_key.to_string()); - // Ok(wallet) - // } - - pub fn sss_sign(&self, msg: &str) { + fn sss_sign(&self, msg: &str) { let k_hash = keccak256(msg.as_bytes()); println!("k_hash: {:?}", &k_hash); let s = hex::encode(&k_hash); @@ -228,7 +219,7 @@ impl Wallet { println!("recover: {:?}", secret_b.to_str_radix(16)); } - pub fn sign(&self, msg: S) -> Result<()> + pub fn sign(&self, msg: S) -> Result<(String)> where S: AsRef<[u8]>, { @@ -251,6 +242,6 @@ impl Wallet { write!(s, "{:02x}", rv).unwrap(); println!("normal sigx: {:?}", s); - Ok(()) + Ok((s)) } }