diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..4c2f513 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,64 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in library 'rustwallet'", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib", + "--package=rustwallet" + ], + "filter": { + "name": "rustwallet", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug example 'test'", + "cargo": { + "args": [ + "build", + "--example=test", + "--package=rustwallet" + ], + "filter": { + "name": "test", + "kind": "example" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in example 'test'", + "cargo": { + "args": [ + "test", + "--no-run", + "--example=test", + "--package=rustwallet" + ], + "filter": { + "name": "test", + "kind": "example" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 1faedd1..126ea16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + [[package]] name = "bitflags" version = "1.3.2" @@ -1202,6 +1208,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7649a0b3ffb32636e60c7ce0d70511eda9c52c658cd0634e194d5a19943aeff" dependencies = [ + "bitcoin_hashes", "rand 0.8.5", "secp256k1-sys 0.6.0", ] diff --git a/Cargo.toml b/Cargo.toml index 4568023..0e2376d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ crate-type = ["staticlib", "lib"] [dependencies] anyhow = "1.0.65" openssl = { version = "0.10.41", features = ["vendored"] } -secp256k1 = { version = "0.24.0", features = ["rand"] } +secp256k1 = { version = "0.24.0", features = ["rand", "bitcoin_hashes"] } serde = { version = "1.0.145", features = ["derive"]} serde_json = "1.0.85" shamir_secret_sharing = "0.1.1" diff --git a/examples/test.rs b/examples/test.rs index 5b962de..4630522 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -7,7 +7,7 @@ use std::ffi::CStr; //use rustylib::gen::{CWallet}; use rustwallet::{ - fetch_cwallet, free_cwallet, generate_cwallet, save_wallet, CWallet, + fetch_cwallet, free_cwallet, generate_cwallet, save_wallet, sign, CWallet, }; fn main() { @@ -23,6 +23,7 @@ fn main() { println!("---- fetching the saved wallet to be exposed to C-side ----"); let fetched = fetch_cwallet(); print_wallet(&fetched); + sign(); free_cwallet(wallet); // 对应 generate_cwallet() free_cwallet(fetched); // 对应 fetch_wallet() diff --git a/src/lib.rs b/src/lib.rs index a6d239e..f78e33a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,6 +67,25 @@ pub unsafe extern "C" fn fetch_cwallet() -> CWallet { 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 diff --git a/src/wallet/wallet_impl.rs b/src/wallet/wallet_impl.rs index 4749c01..d2c977c 100644 --- a/src/wallet/wallet_impl.rs +++ b/src/wallet/wallet_impl.rs @@ -1,11 +1,16 @@ use anyhow::Result; +use secp256k1::ecdsa::Signature; use secp256k1::rand::rngs::OsRng; -use secp256k1::{PublicKey, SecretKey}; +use secp256k1::{PublicKey, SecretKey, Message}; +use secp256k1::hashes::sha256; use serde::{Deserialize, Serialize}; use std::io::BufWriter; +use std::str::FromStr; use std::{fs::OpenOptions, io::BufReader}; use tiny_keccak::keccak256; use web3::types::Address; +use std::str; +use core::fmt::Write; pub fn generate_keypair() -> (SecretKey, PublicKey) { let secp = secp256k1::Secp256k1::new(); @@ -20,6 +25,7 @@ pub fn public_key_address(public_key: &PublicKey) -> Address { Address::from_slice(&hash[12..]) } + #[derive(Serialize, Deserialize, Debug)] pub struct Wallet { pub secret_key: String, @@ -30,8 +36,16 @@ pub struct Wallet { impl Wallet { pub fn new(secret_key: &SecretKey, public_key: &PublicKey) -> Self { let addr: Address = public_key_address(&public_key); + println!("secret key: {:?}", secret_key); + let mut s = String::with_capacity(2 * 32); + for i in &secret_key.secret_bytes() { + write!(s, "{:02x}", *i); + } + println!("{:?}", s); + + Wallet { - secret_key: format!("{:?}", secret_key), + secret_key: s, public_key: public_key.to_string(), public_address: format!("{:?}", addr), } @@ -56,4 +70,16 @@ impl Wallet { let wallet: Wallet = serde_json::from_reader(buf_reader)?; Ok(wallet) } + + pub fn sign(&self, msg: &str) -> Result { + let secp = secp256k1::Secp256k1::new(); + let message = Message::from_hashed_data::(msg.as_bytes()); + println!("secret key str: {:?}", self.secret_key); + println!("message: {:?}", message); + let pk = SecretKey::from_str(&self.secret_key).expect("32 bytes, within curve order"); + println!("secret key: {:?}", pk); + // let sig = secp.sign_ecdsa(&message, &pk); + let sig = secp.sign_ecdsa(&message, &pk); + Ok(sig) + } } diff --git a/wallet.json b/wallet.json index 968c6e4..9e363dd 100644 --- a/wallet.json +++ b/wallet.json @@ -1,5 +1,5 @@ { - "secret_key": "SecretKey(#d3bfbf530f3823ca)", - "public_key": "026c148cde34fead14781bcea7c51a0e9384a7356f3093af1c10d0734da07cf243", - "public_address": "0x4b1636199d65f39c9a4be4a6423b5982db2f1f3b" + "secret_key": "4877e4466ed17b3fa3c5040760a8401bc26565126bd611fdbd903a4652a26b37", + "public_key": "03a0b65abcf64937afff82590b1580add0a3a344e00f209de388dd1378f8162419", + "public_address": "0x5f88990fa8ad8c6e8c33929a685fadec146102f4" } \ No newline at end of file