Skip to content

Commit

Permalink
chore: modify bch and ltc transaction utxo to full path
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoguang1010 committed Mar 21, 2024
1 parent 92e8bcf commit 055ba3c
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 92 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
1 change: 0 additions & 1 deletion imkey-core/ikc-wallet/coin-bitcoin/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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};
Expand Down
5 changes: 1 addition & 4 deletions imkey-core/ikc-wallet/coin-bitcoin/src/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use crate::address::BtcAddress;
use crate::common::{
address_verify, get_address_version, get_xpub_data, secp256k1_sign_verify, TransTypeFlg,
TxSignResult,
};
use crate::common::{address_verify, get_address_version, TransTypeFlg, TxSignResult};
use crate::Result;
use bitcoin::blockdata::{opcodes, script::Builder};
use bitcoin::consensus::{serialize, Encodable};
Expand Down
8 changes: 1 addition & 7 deletions imkey-core/ikc-wallet/coin-bitcoin/src/usdt_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,7 @@ impl BtcTransaction {
}

//utxo address verify
let utxo_pub_key_vec = address_verify(
&self.unspents,
// pub_key,
// hex::decode(chain_code).unwrap().as_slice(),
network,
TransTypeFlg::BTC,
)?;
let utxo_pub_key_vec = address_verify(&self.unspents, network, TransTypeFlg::BTC)?;

//add change output
let mut txouts: Vec<TxOut> = Vec::new();
Expand Down
48 changes: 24 additions & 24 deletions imkey-core/ikc-wallet/coin-btc-fork/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use bitcoin::Network;
use bitcoin::{Address, 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::convert::TryFrom;
Expand All @@ -26,30 +26,30 @@ 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 public_key_obj = Secp256k1PublicKey::from_str(public_key)?;

//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: public_key_obj,
chain_code: chain_code_obj,
};

let bitcoin_secp = BitcoinSecp256k1::new();
if !utxo.derived_path.is_empty() {
let index_number_vec: Vec<&str> = utxo.derived_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)?;
let extend_public_key = if !utxo.derived_path.is_empty() {
let xpub_data = get_xpub_data(&utxo.derived_path, false)?;
let public_key = &xpub_data[..130];
let chain_code = &xpub_data[130..194];
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()),
}
}
} else {
let public_key_obj = Secp256k1PublicKey::from_str(public_key)?;
let chain_code_obj = ChainCode::try_from(chain_code)?;
ExtendedPubKey {
network,
depth: 0,
parent_fingerprint: Default::default(),
child_number: ChildNumber::from_normal_idx(0)?,
public_key: public_key_obj,
chain_code: chain_code_obj,
}
};

let se_gen_address = match trans_type_flg {
TransTypeFlg::BTC => Address::p2pkh(
Expand Down
35 changes: 23 additions & 12 deletions imkey-core/ikc-wallet/coin-btc-fork/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,23 @@ impl BtcForkTransaction {
if y >= utxo_pub_key_vec.len() {
break;
}
let sign_path = if self
.tx_input
.unspents
.get(y)
.unwrap()
.derived_path
.is_empty()
{
path_str.as_str()
} else {
self.tx_input.unspents.get(y).unwrap().derived_path.as_str()
};
let btc_sign_apdu = BtcForkApdu::btc_fork_sign(
0x4A,
y as u8,
EcdsaSighashType::All.to_u32() as u8,
format!(
"{}{}",
path_str,
self.tx_input.unspents.get(y).unwrap().derived_path
)
.as_str(),
sign_path,
);
//sign data
let btc_sign_apdu_return = send_apdu(btc_sign_apdu)?;
Expand Down Expand Up @@ -416,9 +423,13 @@ impl BtcForkTransaction {
data.insert(0, data.len() as u8);
//address
let mut address_data: Vec<u8> = vec![];
let sign_path = format!("{}{}", path_str, unspent.derived_path);
address_data.push(sign_path.as_bytes().len() as u8);
address_data.extend_from_slice(sign_path.as_bytes());
if unspent.derived_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.derived_path.as_bytes().len() as u8);
address_data.extend_from_slice(unspent.derived_path.as_bytes());
}

data.extend(address_data.iter());
if index == self.tx_input.unspents.len() - 1 {
Expand Down Expand Up @@ -595,7 +606,7 @@ mod tests {
amount: 1000000,
address: "myxdgXjCRgAskD2g1b6WJttJbuv67hq6sQ".to_string(),
script_pub_key: "76a914ca4d8acded69ce4f05d0925946d261f86c675fd888ac".to_string(),
derived_path: "0/0".to_string(),
derived_path: "m/44'/2'/0'/0/0".to_string(),
sequence: 0,
};
let mut unspents = Vec::new();
Expand Down Expand Up @@ -640,7 +651,7 @@ mod tests {
amount: 1000000,
address: "myxdgXjCRgAskD2g1b6WJttJbuv67hq6sQ".to_string(),
script_pub_key: "76a914ca4d8acded69ce4f05d0925946d261f86c675fd888ac".to_string(),
derived_path: "0/0".to_string(),
derived_path: "m/44'/2'/0'/0/0".to_string(),
sequence: 0,
};
let mut unspents = Vec::new();
Expand Down Expand Up @@ -684,7 +695,7 @@ mod tests {
amount: 19850000,
address: "M7xo1Mi1gULZSwgvu7VVEvrwMRqngmFkVd".to_string(),
script_pub_key: "76a914ca4d8acded69ce4f05d0925946d261f86c675fd888ac".to_string(),
derived_path: "0/0".to_string(),
derived_path: "m/44'/2'/0'/0/0".to_string(),
sequence: 0,
}];
let tx_input = BtcForkTxInput {
Expand Down

0 comments on commit 055ba3c

Please sign in to comment.