Skip to content

Commit

Permalink
chore: modify btc、ltc、bch transaction utxo path to full path for ikc (#…
Browse files Browse the repository at this point in the history
…79)

* chore: modify btc transaction utxo path to full path

* chore: modify bch and ltc transaction utxo to full path
  • Loading branch information
xiaoguang1010 authored Mar 22, 2024
1 parent 03022dc commit 32229dd
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 243 deletions.
70 changes: 37 additions & 33 deletions imkey-core/ikc-wallet/coin-bch/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use bitcoin::util::bip32::{ChainCode, ChildNumber, ExtendedPubKey};
use bitcoin::{Address, PublicKey};
use ikc_common::apdu::{ApduCheck, BtcForkApdu, CoinCommonApdu};
use ikc_common::error::CoinError;
use ikc_common::utility::sha256_hash;
use ikc_common::utility::{hex_to_bytes, sha256_hash};
use ikc_device::device_binding::KEY_MANAGER;
use ikc_transport::message::send_apdu;
use secp256k1::{ecdsa::Signature, Message, PublicKey as Secp256k1PublicKey, Secp256k1};
Expand All @@ -26,41 +26,45 @@ pub fn address_verify(
) -> Result<Vec<String>> {
let mut utxo_pub_key_vec: Vec<String> = vec![];
for utxo in utxos {
//get utxo public key
let secp256k1_pubkey = Secp256k1PublicKey::from_str(public_key)?;
let public_key_obj = PublicKey {
compressed: true,
inner: secp256k1_pubkey,
};
//gen chain code obj
let chain_code_obj = ChainCode::try_from(chain_code)?;
//build extended public key
let mut extend_public_key = ExtendedPubKey {
network: network,
depth: 0,
parent_fingerprint: Default::default(),
child_number: ChildNumber::from_normal_idx(0)?,
public_key: secp256k1_pubkey,
chain_code: chain_code_obj,
};

let bitcoin_secp = BitcoinSecp256k1::new();

let se_gen_address_str = if utxo.derive_path.is_empty() {
Address::p2pkh(&public_key_obj, network).to_string()
let (se_gen_address_str, extend_public_key) = if utxo.derive_path.is_empty() {
let secp256k1_pubkey = Secp256k1PublicKey::from_str(public_key)?;
let public_key_obj = PublicKey {
compressed: true,
inner: secp256k1_pubkey,
};
let chain_code_obj = ChainCode::try_from(chain_code)?;
(
Address::p2pkh(&public_key_obj, network).to_string(),
ExtendedPubKey {
network,
depth: 0,
parent_fingerprint: Default::default(),
child_number: ChildNumber::from_normal_idx(0)?,
public_key: secp256k1_pubkey,
chain_code: chain_code_obj,
},
)
} else {
let index_number_vec: Vec<&str> = utxo.derive_path.as_str().split('/').collect();

for index_number in index_number_vec {
let test_chain_number =
ChildNumber::from_normal_idx(index_number.parse().unwrap())?;
extend_public_key = extend_public_key.ckd_pub(&bitcoin_secp, test_chain_number)?;
}
Address::p2pkh(
&PublicKey::from_str(extend_public_key.public_key.to_string().as_str())?,
let xpub_data = get_xpub_data(&utxo.derive_path, false)?;
let public_key = &xpub_data[..130];
let chain_code = &xpub_data[130..194];
let extend_public_key = ExtendedPubKey {
network,
depth: 0,
parent_fingerprint: Default::default(),
child_number: ChildNumber::from_normal_idx(0)?,
public_key: Secp256k1PublicKey::from_str(public_key)?,
chain_code: ChainCode::from(hex_to_bytes(chain_code)?.as_slice()),
};

(
Address::p2pkh(
&PublicKey::from_str(extend_public_key.public_key.to_string().as_str())?,
network,
)
.to_string(),
extend_public_key,
)
.to_string()
};

let utxo_address = utxo.address.clone();
Expand Down
25 changes: 14 additions & 11 deletions imkey-core/ikc-wallet/coin-bch/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,13 @@ impl BchTransaction {
data.insert(0, data.len() as u8);
//address
let mut address_data: Vec<u8> = vec![];
let sign_path = format!("{}{}", path_str, unspent.derive_path);
address_data.push(sign_path.as_bytes().len() as u8);
address_data.extend_from_slice(sign_path.as_bytes());

if unspent.derive_path.is_empty() {
address_data.push(path_str.as_bytes().len() as u8);
address_data.extend_from_slice(path_str.as_bytes());
} else {
address_data.push(unspent.derive_path.as_bytes().len() as u8);
address_data.extend_from_slice(unspent.derive_path.as_bytes());
}
data.extend(address_data.iter());
if index == self.unspents.len() - 1 {
sign_apdu_vec.push(BtcForkApdu::btc_fork_segwit_sign(0x48, true, 0x01, data));
Expand Down Expand Up @@ -362,7 +365,7 @@ mod tests {
amount: 100000,
address: "qzld7dav7d2sfjdl6x9snkvf6raj8lfxjcj5fa8y2r".to_string(),
script_pubkey: "76a91488d9931ea73d60eaf7e5671efc0552b912911f2a88ac".to_string(),
derive_path: "0/0".to_string(),
derive_path: "m/44'/145'/0'/0/0".to_string(),
sequence: 0,
};
let mut utxos = Vec::new();
Expand Down Expand Up @@ -398,7 +401,7 @@ mod tests {
amount: 100000,
address: "qzld7dav7d2sfjdl6x9snkvf6raj8lfxjcj5fa8y2r".to_string(),
script_pubkey: "76a91488d9931ea73d60eaf7e5671efc0552b912911f2a88ac".to_string(),
derive_path: "0/0".to_string(),
derive_path: "m/44'/145'/0'/0/0".to_string(),
sequence: 0,
};
let utxo2 = Utxo {
Expand All @@ -407,7 +410,7 @@ mod tests {
amount: 500000,
address: "qzld7dav7d2sfjdl6x9snkvf6raj8lfxjcj5fa8y2r".to_string(),
script_pubkey: "76a91488d9931ea73d60eaf7e5671efc0552b912911f2a88ac".to_string(),
derive_path: "0/0".to_string(),
derive_path: "m/44'/145'/0'/0/0".to_string(),
sequence: 0,
};
let mut utxos = Vec::new();
Expand Down Expand Up @@ -444,7 +447,7 @@ mod tests {
amount: 100000,
address: "qzld7dav7d2sfjdl6x9snkvf6raj8lfxjcj5fa8y2r".to_string(),
script_pubkey: "76a91488d9931ea73d60eaf7e5671efc0552b912911f2a88ac".to_string(),
derive_path: "0/0".to_string(),
derive_path: "m/44'/145'/0'/0/0".to_string(),
sequence: 0,
};
let utxo2 = Utxo {
Expand All @@ -453,7 +456,7 @@ mod tests {
amount: 500000,
address: "qzld7dav7d2sfjdl6x9snkvf6raj8lfxjcj5fa8y2r".to_string(),
script_pubkey: "76a91488d9931ea73d60eaf7e5671efc0552b912911f2a88ac".to_string(),
derive_path: "0/0".to_string(),
derive_path: "m/44'/145'/0'/0/0".to_string(),
sequence: 0,
};
let mut utxos = Vec::new();
Expand Down Expand Up @@ -490,7 +493,7 @@ mod tests {
amount: 100000,
address: "qzld7dav7d2sfjdl6x9snkvf6raj8lfxjcj5fa8y2r".to_string(),
script_pubkey: "76a91488d9931ea73d60eaf7e5671efc0552b912911f2a88ac".to_string(),
derive_path: "0/0".to_string(),
derive_path: "m/44'/145'/0'/0/0".to_string(),
sequence: 0,
};
let utxo2 = Utxo {
Expand All @@ -499,7 +502,7 @@ mod tests {
amount: 500000,
address: "qzld7dav7d2sfjdl6x9snkvf6raj8lfxjcj5fa8y2r".to_string(),
script_pubkey: "76a91488d9931ea73d60eaf7e5671efc0552b912911f2a88ac".to_string(),
derive_path: "0/0".to_string(),
derive_path: "m/44'/145'/0'/0/0".to_string(),
sequence: 0,
};
let mut utxos = Vec::new();
Expand Down
27 changes: 9 additions & 18 deletions imkey-core/ikc-wallet/coin-bitcoin/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::transaction::Utxo;
use crate::Result;
use bitcoin::secp256k1::Secp256k1 as BitcoinSecp256k1;
use bitcoin::util::base58;
use bitcoin::util::bip32::{ChainCode, ChildNumber, ExtendedPubKey};
use bitcoin::{Address, Network, PublicKey};
use ikc_common::apdu::{ApduCheck, BtcApdu, CoinCommonApdu};
use ikc_common::error::CoinError;
use ikc_common::utility::sha256_hash;
use ikc_common::utility::{hex_to_bytes, sha256_hash};
use ikc_transport::message::send_apdu;
use secp256k1::{ecdsa::Signature, Message, PublicKey as Secp256k1PublicKey, Secp256k1};
use std::str::FromStr;
Expand All @@ -16,33 +15,25 @@ utxo address verify
*/
pub fn address_verify(
utxos: &Vec<Utxo>,
public_key: &str,
chain_code: &[u8],
network: Network,
trans_type_flg: TransTypeFlg,
) -> Result<Vec<String>> {
let mut utxo_pub_key_vec: Vec<String> = vec![];
for utxo in utxos {
//get utxo public key
let public_key_obj = Secp256k1PublicKey::from_str(public_key)?;
//gen chain code obj
let chain_code_obj = ChainCode::from(chain_code);
//build extended public key
//get xpub and sign data
let xpub_data = get_xpub_data(&utxo.derive_path, false)?;
//parsing xpub data
let public_key = &xpub_data[..130];
let chain_code = &xpub_data[130..194];
let mut extend_public_key = ExtendedPubKey {
network: network,
network,
depth: 0,
parent_fingerprint: Default::default(),
child_number: ChildNumber::from_normal_idx(0)?,
public_key: public_key_obj,
chain_code: chain_code_obj,
public_key: Secp256k1PublicKey::from_str(public_key)?,
chain_code: ChainCode::from(hex_to_bytes(chain_code)?.as_slice()),
};

let bitcoin_secp = BitcoinSecp256k1::new();
let index_number_vec: Vec<&str> = utxo.derive_path.as_str().split('/').collect();
for index_number in index_number_vec {
let test_chain_number = ChildNumber::from_normal_idx(index_number.parse().unwrap())?;
extend_public_key = extend_public_key.ckd_pub(&bitcoin_secp, test_chain_number)?;
}
//verify address
let se_gen_address: Result<String> = match trans_type_flg {
TransTypeFlg::BTC => Ok(Address::p2pkh(
Expand Down
Loading

0 comments on commit 32229dd

Please sign in to comment.