Privacy concerns of a Transaction and it's implication in Coinselection
Typically when a bitcoin transaction is created using bitcoin client or a wallet for a single user one can conclude that all the inputs in the transaction belong to a single user. We might not able to deduce who the user is but it's clear that all the addresses in that partucular transaction inputs belong to a single user.
More unique addresses in a transaction means an attacker can deduce that all those different addresses belongs to a single user, this gives the attacker an ability to group addresses together for single users using this heuristic. In most crypto exchanges because of KYC and other login details one can clearly associate some addresses with a known user. Now if the attacker can successfully group certain addresses together it means they can potentially deduce that the particular known user has at least n amount of bitcoin.
The goal of the tutorial is to demonstrate how coinselection impacts the privacy of users in bitcoin blockchain.
Counting number of unique addresses in a transaction using rust
In our analysis we are going to fetch a block of certain height and analyze the transactions within it.
The following code snippet demonstrates how to do this using rust-bitcoincore_rpc crate.
fn get_block(client: &Client, block_height: u64) -> Result<bitcoin::Block, bitcoincore_rpc::Error> {
let block = client.get_block_hash(block_height)?; // fetch the hash of the block
client.get_block(&block) // return the complete block with another rpc call
}The following is the function that we want to complete
fn txs_sort_unique_input_addrs(client: &Client, block_height: u64) -> Result<Vec<(Transaction, u32)>, bitcoincore_rpc::Error> {
// Fetching the basic data necessary and intializing the variables
let block = get_block(client, block_height)?;
let txs = block.txdata;
let mut result: Vec<(Transaction, u32)> = vec![];
}We need to keep track of unique addresses, the datastructure that helps us achieve that goal is a Hashset. Now we iterate through every transaction and compute the unique addresses used in each of them, using HashSet.
The extract_from_TxIn function looks like this,
So in order to extract address from the transaction input we have to get information about the transaction where the input was the output (TxOut). The following code demonstrates how to do it,
From the script_pubkey of the previous output it is possible to extract the address of the current transaction input using the following,
Putting it all together the entire code can be found here
Last updated