#![allow(dead_code)]
#![allow(unused_imports)]
use bitcoin_request::command::{
get_best_block_hash::GetBestBlockHashCommand,
get_block::{
GetBlockCommand, GetBlockCommandResponse, GetBlockCommandTransactionResponse,
GetBlockCommandVerbosity,
},
get_block_count::GetBlockCountCommand,
get_block_hash::GetBlockHashCommand,
get_block_header::GetBlockHeaderCommand,
get_block_stats::{GetBlockStatsCommand, StatsArgumentChoices, TargetBlockArgument},
get_blockchain_info::GetBlockchainInfoCommand,
get_chain_tips::GetChainTipsCommand,
get_chain_tx_stats::GetChainTxStatsCommand,
get_difficulty::GetDifficultyCommand,
get_mining_info::GetMiningInfoCommand,
get_network_hash_ps::GetNetworkHashPsCommand,
get_raw_transaction::{GetRawTransactionCommand, GetRawTransactionCommandResponse, Vin},
get_tx_out::GetTxOutCommand,
get_tx_out_set_info::GetTxOutSetInfoCommand,
CallableCommand,
};
use bitcoin_request::{Blockhash, BlockhashHexEncoded};
use jsonrpc::simple_http::{self, SimpleHttpTransport};
use jsonrpc::Client;
use std::env;
fn mean(numbers: &Vec<i32>) -> f32 {
let sum: i32 = numbers.iter().sum();
sum as f32 / numbers.len() as f32
}
fn median(numbers: &mut Vec<i32>) -> i32 {
numbers.sort();
let mid = numbers.len() / 2;
if numbers.len() % 2 == 0 {
mean(&vec![numbers[mid - 1], numbers[mid]]) as i32
} else {
numbers[mid]
}
}
fn client(url: &str, user: &str, pass: &str) -> Result<Client, simple_http::Error> {
let t = SimpleHttpTransport::builder()
.url(url)?
.auth(user, Some(pass))
.build();
Ok(Client::with_transport(t))
}
fn get_total_fees_for_block(
client: &Client,
get_block_command_response: GetBlockCommandResponse,
) -> (f64, f64, Vec<i32>) {
match get_block_command_response {
GetBlockCommandResponse::Block(block) => {
let mut total_vin_value = 0.0;
let mut total_vout_value = 0.0;
let mut total_coinbase_vout_value = 0.0;
let transaction_count = block.tx.len();
let mut sats_per_bytes: Vec<i32> = vec![];
for tx in block.tx.into_iter().rev() {
match tx {
GetBlockCommandTransactionResponse::Raw(transaction) => {
let txid = transaction.txid;
let full_transaction = GetRawTransactionCommand::new(txid)
.verbose(true)
.call(&client);
match full_transaction {
GetRawTransactionCommandResponse::SerializedHexEncodedData(_s) => {}
GetRawTransactionCommandResponse::Transaction(t) => {
let top_level_txid = &t.txid;
let mut transaction_vin_value = 0.0;
let mut transaction_vout_value = 0.0;
for vin in &t.vin {
match vin {
Vin::Coinbase(cbv) => {
}
Vin::NonCoinbase(v) => {
let vin_transaction =
GetRawTransactionCommand::new(v.txid.clone())
.verbose(true)
.call(&client);
match vin_transaction {
GetRawTransactionCommandResponse::SerializedHexEncodedData(_s) => {
}
GetRawTransactionCommandResponse::Transaction(t) => {
let vin_vout_index = v.vout as usize;
let vout = &t.vout[vin_vout_index];
total_vin_value= total_vin_value+ vout.value;
transaction_vin_value= transaction_vin_value + vout.value;
}
}
}
}
}
if t.is_coinbase_transaction() {
for vout in &t.vout {
total_coinbase_vout_value =
vout.value + total_coinbase_vout_value
}
} else {
for vout in &t.vout {
total_vout_value = total_vout_value + vout.value;
transaction_vout_value =
transaction_vout_value + vout.value;
}
}
let fee_for_transaction =
transaction_vin_value - transaction_vout_value;
let virtual_size = t.vsize;
let sats_per_byte = (fee_for_transaction * 100_000_000.0) as f64
/ virtual_size as f64;
sats_per_bytes.push(sats_per_byte as i32);
}
}
}
GetBlockCommandTransactionResponse::Id(id) => {}
}
}
let difference: f64 = total_vin_value - total_vout_value;
println!("transaction_count: {}", transaction_count);
let median_sats_per_byte = median(&mut sats_per_bytes);
println!("media transaction fee_per_byte: {:?}", median_sats_per_byte);
(difference, total_coinbase_vout_value, sats_per_bytes)
}
GetBlockCommandResponse::BlockHash(hash) => {
todo!();
}
}
}
fn main() {
let password = env::var("BITCOIND_PASSWORD").expect("BITCOIND_PASSWORD env variable not set");
let username = env::var("BITCOIND_USERNAME").expect("BITCOIND_USERNAME env variable not set");
let client = client("127.0.0.1:8332", &username, &password).expect("failed to create client");
let blockhash_hex_encoded = BlockhashHexEncoded(
"00000000000000000007d1712328c3b95adc170e3e04b2499c04a4ee2905f72e".to_string(),
);
let best_block_hash_response =
GetBestBlockHashCommand::new(blockhash_hex_encoded).call(&client);
println!("{:?}", best_block_hash_response);
let best_block_hash = best_block_hash_response.0;
let response = GetBlockCommand::new(best_block_hash)
.verbosity(GetBlockCommandVerbosity::BlockObjectWithoutTransactionInformation)
.call(&client);
println!("{:#?}", response);
let block_count = GetBlockCountCommand::new().call(&client);
println!("{:#?}", block_count);
let newest_block_hash_response = GetBlockHashCommand::new(block_count.0).call(&client);
println!("{:#?}", newest_block_hash_response);
let newest_block_hash = newest_block_hash_response.0;
let block_stats_response =
GetBlockStatsCommand::new(TargetBlockArgument::Hash(newest_block_hash))
.add_selective_stats(vec![StatsArgumentChoices::MedianTime])
.call(&client);
println!("{:#?}", block_stats_response);
let get_chain_tips_response = GetChainTipsCommand::new().call(&client);
println!("{:#?}", get_chain_tips_response);
let get_chain_tx_stats_response = GetChainTxStatsCommand::new() .call(&client);
println!("HERE:{:#?}", get_chain_tx_stats_response);
let get_difficulty_response = GetDifficultyCommand::new().call(&client);
println!("{:#?}", get_difficulty_response);
let tx_id = "df4f4e724eb1b9b4f5047a99ff215e239205d81d0bd01f9608c8105ce09959d7".to_string();
let get_tx_out_response = GetTxOutCommand::new(tx_id, 0)
.include_mempool(true) .call(&client);
println!("{:#?}", get_tx_out_response);
let get_mining_info_response = GetMiningInfoCommand::new().call(&client);
println!("{:#?}", get_mining_info_response);
let get_network_hash_ps_response = GetNetworkHashPsCommand::new().call(&client);
println!("{:#?}", get_network_hash_ps_response);
let get_tx_out_set_info_response = GetTxOutSetInfoCommand::new().call(&client);
println!("{:#?}", get_tx_out_set_info_response);
}