transaction and block deserialization

This commit is contained in:
debris 2016-08-15 16:35:07 +02:00
parent 01be3fec5b
commit 6147a3bd51
4 changed files with 99 additions and 0 deletions

View File

@ -1,5 +1,6 @@
use block_header::BlockHeader;
use compact_integer::CompactInteger;
use reader::{Deserializable, Reader, Error as ReaderError};
use stream::{Serializable, Stream};
use transaction::Transaction;
@ -16,3 +17,18 @@ impl Serializable for Block {
.append_list(&self.transactions);
}
}
impl Deserializable for Block {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let block_header = try!(reader.read());
let tx_len = try!(reader.read::<CompactInteger>());
let transactions = try!(reader.read_list(tx_len.into()));
let result = Block {
block_header: block_header,
transactions: transactions,
};
Ok(result)
}
}

View File

@ -8,6 +8,12 @@ use reader::{Deserializable, Reader, Error as ReaderError};
#[derive(Default, Debug, Clone, Copy, PartialEq)]
pub struct CompactInteger(u64);
impl From<CompactInteger> for usize {
fn from(i: CompactInteger) -> Self {
i.0 as usize
}
}
impl From<CompactInteger> for u64 {
fn from(i: CompactInteger) -> Self {
i.0

View File

@ -37,6 +37,16 @@ impl<'a> Reader<'a> {
self.read += len;
Ok(result)
}
pub fn read_list<T>(&mut self, len: usize) -> Result<Vec<T>, Error> where T: Deserializable {
let mut result = vec![];
for _ in 0..len {
result.push(try!(self.read()));
}
Ok(result)
}
}
impl Deserializable for i32 {

View File

@ -2,6 +2,7 @@
//! Bitcoin trainsaction.
//! https://en.bitcoin.it/wiki/Protocol_documentation#tx
use reader::{Deserializable, Reader, Error as ReaderError};
use stream::{Serializable, Stream};
use compact_integer::CompactInteger;
@ -19,6 +20,20 @@ impl Serializable for OutPoint {
}
}
impl Deserializable for OutPoint {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let mut hash = [0u8; 32];
hash.copy_from_slice(try!(reader.read_bytes(32)));
let index = try!(reader.read());
let result = OutPoint {
hash: hash,
index: index,
};
Ok(result)
}
}
#[derive(Debug)]
pub struct TransactionInput {
previous_output: OutPoint,
@ -36,6 +51,23 @@ impl Serializable for TransactionInput {
}
}
impl Deserializable for TransactionInput {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let previous_output = try!(reader.read());
let signature_script_len = try!(reader.read::<CompactInteger>());
let signature_script = try!(reader.read_bytes(signature_script_len.into())).to_vec();
let sequence = try!(reader.read());
let result = TransactionInput {
previous_output: previous_output,
signature_script: signature_script,
sequence: sequence,
};
Ok(result)
}
}
#[derive(Debug)]
pub struct TransactionOutput {
value: u64,
@ -51,6 +83,21 @@ impl Serializable for TransactionOutput {
}
}
impl Deserializable for TransactionOutput {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let value = try!(reader.read());
let pk_script_len = try!(reader.read::<CompactInteger>());
let pk_script = try!(reader.read_bytes(pk_script_len.into())).to_vec();
let result = TransactionOutput {
value: value,
pk_script: pk_script,
};
Ok(result)
}
}
#[derive(Debug)]
pub struct Transaction {
version: i32,
@ -70,3 +117,23 @@ impl Serializable for Transaction {
.append(&self.lock_time);
}
}
impl Deserializable for Transaction {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let version = try!(reader.read());
let tx_inputs_len= try!(reader.read::<CompactInteger>());
let tx_inputs = try!(reader.read_list(tx_inputs_len.into()));
let tx_outputs_len= try!(reader.read::<CompactInteger>());
let tx_outputs = try!(reader.read_list(tx_outputs_len.into()));
let lock_time = try!(reader.read());
let result = Transaction {
version: version,
transaction_inputs: tx_inputs,
transaction_outputs: tx_outputs,
lock_time: lock_time,
};
Ok(result)
}
}