From 34adb75d40785944f06efe8182b9173e79fc5f06 Mon Sep 17 00:00:00 2001 From: cygnet Date: Wed, 27 Mar 2024 14:42:36 +0100 Subject: [PATCH] Add get_pubkeys_from_transaction for receiving utils --- Cargo.toml | 4 +++- src/utils/receiving.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7b8f2cf..cb39d35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,9 +16,10 @@ name = "silentpayments" crate-type = ["lib"] [features] -default = ["sending", "receiving"] +default = ["sending", "receiving", "bitcoin"] sending = [] receiving = [] +bitcoin = ["dep:bitcoin"] [dependencies] secp256k1 = {version = "0.28.1", features = ["rand"] } @@ -28,3 +29,4 @@ bimap = "0.6" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" bitcoin_hashes = "0.13.0" +bitcoin = { version = "0.31", optional = true } diff --git a/src/utils/receiving.rs b/src/utils/receiving.rs index f389e67..99d6e47 100644 --- a/src/utils/receiving.rs +++ b/src/utils/receiving.rs @@ -10,6 +10,9 @@ use bitcoin_hashes::{hash160, Hash}; use secp256k1::{Parity::Even, XOnlyPublicKey}; use secp256k1::{PublicKey, SecretKey}; +#[cfg(feature = "bitcoin")] +use bitcoin::{ScriptBuf, TxIn}; + use super::{hash::calculate_input_hash, COMPRESSED_PUBKEY_SIZE, NUMS_H}; /// Calculate the tweak data of a transaction. @@ -235,3 +238,32 @@ fn is_p2sh(spk: &[u8]) -> bool { fn is_p2pkh(spk: &[u8]) -> bool { matches!(spk, [OP_DUP, OP_HASH160, OP_PUSHBYTES_20, .., OP_EQUALVERIFY, OP_CHECKSIG] if spk.len() == 25) } + +/// Get the public keys from a set of input data, using rust-bitcoin structs. +/// +/// # Arguments +/// +/// * `inputs` - A Vec that contains the transaction inputs (TxIn) along with the ScriptPubKey from the previous output +/// +/// # Returns +/// +/// On success, this function returns a list of all eligible public keys from a transaction as a `Vec`. If the `Vec` is of length 0, this transaction is not eligible to be a silent payment. +/// +/// # Errors +/// +/// This function will error if: +/// +/// * The provided Vin data is incorrect. This shouldn't occur if the provided input from a valid transaction. +#[cfg(feature = "bitcoin")] +pub fn get_pubkeys_from_transaction(inputs: Vec<(TxIn, ScriptBuf)>) -> Result> { + let mut res = vec![]; + for (txin, spk) in inputs { + let script_sig = txin.script_sig.as_bytes(); + let witness = txin.witness.to_vec(); + + if let Some(pk) = get_pubkey_from_input(script_sig, &witness, spk.as_bytes())? { + res.push(pk); + } + } + Ok(res) +}