Skip to content

Instantly share code, notes, and snippets.

@kannapoix
Created November 16, 2018 14:13
Show Gist options
  • Save kannapoix/d0dcaaa26c7ebff34fedd76293de1c7d to your computer and use it in GitHub Desktop.
Save kannapoix/d0dcaaa26c7ebff34fedd76293de1c7d to your computer and use it in GitHub Desktop.
rust coinjoin sudoku
#[macro_use]
extern crate serde_derive;
mod parse;
use parse::*;
fn main() {
// let mut transactions = vec![];
let block_height = vec![118, 119,120];
let blocks = get_json(get_block_hashes(block_height));
for block in &blocks {
for tx in block["tx"].as_array().unwrap().iter() {
let mut pre_transactions = parse_transaction(tx);
// inputをparse
for transaction in pre_transactions.iter_mut() {
println!("{:#?}", transaction);
for input in transaction.txin.iter_mut() {
parse_input(input);
}
// transactions.push(transaction);
println!("{:#?}", transaction);
}
}
}
// println!("{:?}", transactions);
// 分析
// for block in &blocks {
// println!("{:#?}", block);
//
// }
}
// ----
use std::process::Command;
extern crate serde;
extern crate serde_json;
use self::serde_json::{Value};
#[derive(Deserialize, Debug)]
pub struct Transaction {
txid: String,
pub txin: Vec<TransactionInput>,
txout: Vec<TransactionOutput>,
}
#[derive(Deserialize, Debug)]
pub struct TransactionInput {
txid: String,
vout: u64,
value: f64,
}
#[derive(Deserialize, Debug)]
struct TransactionOutput {
n: u64,
value: f64,
}
impl Transaction {
fn get_fee(&self) {
println!("{:?}", self.txin);
println!("{:?}", self.txout);
}
fn share_coin(&self) {
}
}
// inputのtransaction idから valueを取得する
// todo: return値不要
// inputの値を書き換える
pub fn parse_input(input: &mut TransactionInput){
let mut command_string = String::from("bitcoin-cli getrawtransaction ");
command_string.push_str(&input.txid);
command_string.push_str(" true");
let transaction = Command::new("sh")
.arg("-c")
.arg(command_string)
.output()
.expect("failed to execute process");
let result_str = String::from_utf8_lossy(&transaction.stdout);
let json: Value = serde_json::from_str(&result_str).expect("in parse_input");
let transaction_vec = parse_transaction(&json);
for output in transaction_vec[0].txout.iter() {
if input.vout == output.n {
input.value = output.value
}
}
}
pub fn parse_transaction(tx: &serde_json::Value) -> Vec<Transaction>{
let mut transactions = Vec::new();
let mut transaction = Transaction {
txid: tx["txid"].as_str().unwrap().to_string(),
txin: Vec::new(),
txout: Vec::new(),
};
// inputを取り出し、Vectorにする
let mut input_vec = Vec::new();
for input in tx["vin"].as_array().unwrap().iter(){
// inputを持たないcoinbaseを除外
match &input["vout"] {
serde_json::Value::Null => continue,
_ => (),
}
let input_struct = TransactionInput {
txid: input["txid"].as_str().unwrap().to_string(),
vout: input["vout"].as_u64().unwrap(),
value: 0.0,
};
input_vec.push(input_struct);
}
transaction.txin = input_vec;
// outputuを取り出し、Vectorにする
let mut output_vec = Vec::new();
for output in tx["vout"].as_array().unwrap().iter(){
let output_struct = TransactionOutput {
n: output["n"].as_f64().unwrap() as u64,
value: output["value"].as_f64().unwrap()
};
output_vec.push(output_struct);
}
transaction.txout = output_vec;
transactions.push(transaction);
transactions
}
// bitcoindからのjsonを取得する
pub fn get_json(block_hashes: Vec<String>) -> Vec<serde_json::Value> {
let mut json_vec = Vec::new();
for block_hash in block_hashes.iter() {
let mut command_string = String::from("bitcoin-cli getblock ");
command_string.push_str(&block_hash);
command_string.push_str(" 2");
let block = Command::new("sh")
.arg("-c")
.arg(command_string)
.output()
.expect("failed to execute process");
let result_str = String::from_utf8_lossy(&block.stdout);
let json: Value = serde_json::from_str(&result_str).expect("Error in get_json");
json_vec.push(json)
}
json_vec
}
pub fn get_block_hashes(block_height: Vec<i8>) -> Vec<String> {
// todo: blockhashなかった場合
let mut block_hashes = Vec::new();
for num in block_height.iter() {
let mut command_string = String::from("bitcoin-cli getblockhash ");
command_string.push_str(&num.to_string());
let block_hash = Command::new("sh")
.arg("-c")
.arg(command_string)
.output()
.expect("failed to execute process");
let mut result_str = String::from_utf8_lossy(&block_hash.stdout).to_string();
result_str = result_str.trim().to_string();
block_hashes.push(result_str);
}
block_hashes
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment