Skip to content

Commit

Permalink
Finishing the json parsing and serialization from transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielgusn committed Apr 23, 2024
1 parent 78705dc commit 638410b
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 53 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0", features = ["derive"]}
chrono = "0.4.37"
hex-literal = "0.4.1"
ring = "0.17.8"
Expand Down
51 changes: 30 additions & 21 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#![allow(dead_code, unused)]

mod transactions;
use std::{fs::{self, File}, io};
// use core::panicking::panic;
use std::io::{self, Read};
use std::fs::{self, File};
use std::path::Path;
use serde_json;
use transactions::tx::{Tx, TxInput, TxOutput};

Expand All @@ -17,11 +20,11 @@ pub fn read_mempool(path: &str){
// let file_size = fs::metadata(&file_path).expect("Falha ao ler o arquivo");
// file.sync_all();
// println!("Size: {} File: {}", file);
let transaction_json: serde_json::Value = read_tx_from_file(&file_path);
let transaction_json: Tx = read_tx_from_file(&file_path);

let tx: Tx = convert_json_tx_to_struct(transaction_json);
// let tx: Tx = convert_json_tx_to_struct(transaction_json);

println!("{:?}", tx);
println!("{:?}", transaction_json.vin[0].txid);
// if transaction["vin"][0]["txid"] == "491cd7b98e0eec28eb9a97e061fcd71854ac103bdbc4d8a83b6613394d29489e" {
// println!("{:?}", transaction);
// }
Expand All @@ -31,32 +34,38 @@ pub fn read_mempool(path: &str){
// is_coinbase(tx_in_json);
}

pub fn read_tx_from_file(file_path: &str) -> serde_json::Value {
let contents = fs::read_to_string(file_path)
.expect("Error while reading file");
pub fn read_tx_from_file(file_path: &str) -> Tx {
let mut file_content: String = String::new();
let path = Path::new(file_path);
let mut file = File::open(path).expect("Error while loading file");
file.read_to_string(&mut file_content).expect("File can not be read");

// let contents = fs::read_to_string(file_path)
// .expect("Error while reading file");

let tx_in_json: serde_json::Value = serde_json::from_str(contents.as_str())
.expect("Error parsing file content to JSON");
let tx_in_json: Tx = serde_json::from_str(&file_content).unwrap();
// .expect("Error parsing file content to JSON");

return tx_in_json;
}

pub fn convert_json_tx_to_struct(tx_json: serde_json::Value) -> Tx {
let tx_vin = &tx_json["vin"][0];
let tx_vout = &tx_json["vout"][0];

let mut tx_input_vec: Vec<TxInput> = vec![];
let mut tx_output_vec: Vec<TxOutput> = vec![];
// TODO: this function is with a problem that all the strings are coming with "\".......\""
// pub fn convert_json_tx_to_struct(tx_json: serde_json::Value) -> Tx {
// let tx_vin = &tx_json["vin"][0];
// let tx_vout = &tx_json["vout"][0];

// let mut tx_input_vec: Vec<TxInput> = vec![];
// let mut tx_output_vec: Vec<TxOutput> = vec![];

let tx_input: TxInput = TxInput::new(tx_vin["txid"].to_string(), tx_vin["prevout"]["value"].as_u64().expect("Error while casting tx_in value to u64"), tx_vin["scriptsig"].to_string(), tx_vin["is_coinbase"].as_bool().expect("Error while casting tx_in is_coinbase"));
// let tx_input: TxInput = TxInput::new(tx_vin["txid"].to_string(), tx_vin["prevout"]["value"].as_u64().expect("Error while casting tx_in value to u64"), tx_vin["scriptsig"].to_string(), tx_vin["is_coinbase"].as_bool().expect("Error while casting tx_in is_coinbase"));

let tx_output: TxOutput = TxOutput::new(tx_vout["value"].as_u64().expect("Error while casting tx_out value to u64"), tx_vout["scriptpubkey"].to_string());
// let tx_output: TxOutput = TxOutput::new(tx_vout["value"].as_u64().expect("Error while casting tx_out value to u64"), tx_vout["scriptpubkey"].to_string());

tx_input_vec.push(tx_input);
tx_output_vec.push(tx_output);
// tx_input_vec.push(tx_input);
// tx_output_vec.push(tx_output);

Tx::new(tx_json["version"].as_u64().expect("Error while parsing tx version to u64") as u32, tx_input_vec, tx_output_vec)
}
// Tx::new(tx_json["version"].as_u64().expect("Error while parsing tx version to u64") as u32, tx_input_vec, tx_output_vec)
// }

pub fn is_coinbase(tx: serde_json::Value) -> bool {
let tx_input = &tx["vin"];
Expand Down
2 changes: 1 addition & 1 deletion src/transactions/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod tx;
pub mod tx;
94 changes: 63 additions & 31 deletions src/transactions/tx.rs
Original file line number Diff line number Diff line change
@@ -1,76 +1,108 @@
#![allow(dead_code, unused)]

// use serde::{Serialize, Deserialize}
// use serde_json;
// use ring::digest;

#[derive(Debug)]
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct Tx{
pub version: u32,
pub tx_input: Vec<TxInput>,
pub tx_size: u64,
pub tx_output: Vec<TxOutput>
pub locktime: u32,
pub vin: Vec<TxInput>,
pub vout: Vec<TxOutput>,
// tx_size: u64,
}


impl Tx{
pub fn new (version: u32, tx_input: Vec<TxInput>, tx_output: Vec<TxOutput>) -> Self {
pub fn new (version: u32, locktime: u32, vin: Vec<TxInput>, vout: Vec<TxOutput>) -> Self {
let mut tx_size = 32 + 64;

tx_output.iter().for_each(|output| tx_size += output.get_tx_output_size_in_bytes());
tx_input.iter().for_each(|input| tx_size += input.get_tx_input_size_in_bytes());
vout.iter().for_each(|output| tx_size += output.get_tx_output_size_in_bytes());
vin.iter().for_each(|input| tx_size += input.get_tx_input_size_in_bytes());


Self {
version,
tx_input,
tx_size,
tx_output,
locktime,
vin,
vout,
// tx_size,
}
}

// pub fn get_tx_size(&self) -> u64 {
// self.tx_size
// }
}

#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct TxInput{
tx_id: String,
value: u64,
signature_script: String,
is_coinbase: bool,
pub txid: String,
pub vout: u32,
pub prevout: TxPrevOut,
pub scriptsig: String,
pub scriptsig_asm: String,
pub witness: Vec<String>,
pub is_coinbase: bool,
pub sequence: u64,
}

impl TxInput{

pub fn new(tx_id: String, value: u64, signature_script: String, is_coinbase: bool) -> Self{
pub fn new(txid: String,vout: u32,prevout: TxPrevOut,scriptsig: String,scriptsig_asm: String,witness: Vec<String>,is_coinbase: bool,sequence: u64,) -> Self{
Self{
tx_id,
value,
signature_script,
is_coinbase
txid,
vout,
prevout,
scriptsig,
scriptsig_asm,
witness,
is_coinbase,
sequence,
}
}

fn get_tx_input_size_in_bytes(&self) -> u64{
let sigscript_size: u64 = self.signature_script.len() as u64 * 32;
let tx_id_size: u64 = self.tx_id.len() as u64 * 32;
return 64 + sigscript_size + tx_id_size + 1;
let sigscript_size: u64 = self.scriptsig.len() as u64 * 32;
let txid_size: u64 = self.txid.len() as u64 * 32;
return 64 + sigscript_size + txid_size + 1;
}
}

#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct TxPrevOut{
pub scriptpubkey: String,
pub scriptpubkey_asm: String,
pub scriptpubkey_type: String,
pub scriptpubkey_address: String,
pub value: u64,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct TxOutput {
pub scriptpubkey: String,
pub scriptpubkey_asm: String,
pub scriptpubkey_type: String,
pub scriptpubkey_address: String,
pub value: u64,
pub pk_script: String,
}

impl TxOutput{

pub fn new(value:u64, pk_script: String) -> Self {
pub fn new(scriptpubkey: String, scriptpubkey_asm: String, scriptpubkey_type: String, scriptpubkey_address: String, value: u64,) -> Self {
Self{
value,
pk_script
scriptpubkey,
scriptpubkey_asm,
scriptpubkey_type,
scriptpubkey_address,
value
}
}

pub fn get_tx_output_size_in_bytes(&self) -> u64{
let pk_script_size: u64 = self.pk_script.len() as u64 * 32;
let pk_script_size: u64 = self.scriptpubkey.len() as u64 * 32;
return pk_script_size + 64
}
}
}

0 comments on commit 638410b

Please sign in to comment.