Skip to content

Commit

Permalink
Final mod
Browse files Browse the repository at this point in the history
  • Loading branch information
22388o committed Jan 17, 2025
1 parent 132f2fc commit b8a1b81
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 0 deletions.
73 changes: 73 additions & 0 deletions src/proofs/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/// An error type for handling proof-related issues.
#[derive(Debug)]
pub struct ProofError {
message: String,
}

impl ProofError {
/// Creates a new `ProofError` with a custom message.
pub fn new(msg: &str) -> Self {
Self {
message: msg.to_string(),
}
}
}

impl std::fmt::Display for ProofError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message)
}
}

impl std::error::Error for ProofError {}

/// A custom proof struct for demonstration purposes.
pub struct MyProof {
a: Vec<u8>,
b: Vec<u8>,
}

impl MyProof {
/// Constructor for `MyProof`.
pub fn new(a: Vec<u8>, b: Vec<u8>) -> Self {
Self { a, b }
}
}

/// A trait defining the behavior required for a proof.
pub trait MyProofTrait {
fn verify(&self) -> Result<(), ProofError>;
fn serialize(&self) -> Result<Vec<u8>, ProofError>;
fn deserialize(data: &[u8]) -> Result<Self, ProofError>
where
Self: Sized;
}

impl MyProofTrait for MyProof {
fn verify(&self) -> Result<(), ProofError> {
// Verification logic (example)
println!("Verifying MyProof...");
Ok(())
}

fn serialize(&self) -> Result<Vec<u8>, ProofError> {
// Example serialization logic
let mut serialized = Vec::new();
serialized.extend_from_slice(&self.a);
serialized.extend_from_slice(&self.b);
Ok(serialized)
}

fn deserialize(data: &[u8]) -> Result<Self, ProofError> {
// Example deserialization logic
if data.len() < 2 {
return Err(ProofError::new("Data too short to deserialize"));
}
let mid = data.len() / 2;
let (a, b) = data.split_at(mid);
Ok(Self {
a: a.to_vec(),
b: b.to_vec(),
})
}
}
116 changes: 116 additions & 0 deletions src/transaction/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/// An error type for handling transaction-related issues.
#[derive(Debug)]
pub struct TransactionError {
message: String,
}

impl TransactionError {
/// Creates a new `TransactionError` with a custom message.
pub fn new(msg: &str) -> Self {
Self {
message: msg.to_string(),
}
}
}

impl std::fmt::Display for TransactionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message)
}
}

impl std::error::Error for TransactionError {}

/// A struct representing a transaction input.
#[derive(Debug, Clone)]
pub struct Input {
pub previous_tx: Vec<u8>, // Reference to a previous transaction
pub index: usize, // Output index in the referenced transaction
}

/// A struct representing a transaction output.
#[derive(Debug, Clone)]
pub struct Output {
pub recipient: Vec<u8>, // Address or public key of the recipient
pub amount: u64, // Amount of currency in the output
}

/// A struct representing a transaction.
#[derive(Debug, Clone)]
pub struct Transaction {
pub inputs: Vec<Input>, // List of inputs
pub outputs: Vec<Output>, // List of outputs
}

impl Transaction {
/// Creates a new transaction.
pub fn new(inputs: Vec<Input>, outputs: Vec<Output>) -> Self {
Self { inputs, outputs }
}

/// Verifies that the transaction is valid.
pub fn verify(&self) -> Result<(), TransactionError> {
// Example verification logic
if self.inputs.is_empty() {
return Err(TransactionError::new("Transaction must have at least one input"));
}
if self.outputs.is_empty() {
return Err(TransactionError::new("Transaction must have at least one output"));
}
if self.outputs.iter().any(|output| output.amount == 0) {
return Err(TransactionError::new("Output amounts must be greater than zero"));
}
println!("Transaction is valid!");
Ok(())
}

/// Serializes the transaction into a vector of bytes.
pub fn serialize(&self) -> Result<Vec<u8>, TransactionError> {
let mut serialized = Vec::new();
for input in &self.inputs {
serialized.extend_from_slice(&input.previous_tx);
serialized.extend_from_slice(&input.index.to_le_bytes());
}
for output in &self.outputs {
serialized.extend_from_slice(&output.recipient);
serialized.extend_from_slice(&output.amount.to_le_bytes());
}
Ok(serialized)
}

/// Deserializes a transaction from a vector of bytes.
pub fn deserialize(data: &[u8]) -> Result<Self, TransactionError> {
let mut offset = 0;

// Example logic to reconstruct the transaction (input/output sizes are fixed for simplicity)
let mut inputs = Vec::new();
let mut outputs = Vec::new();

// Deserialize inputs
while offset + 36 <= data.len() {
let previous_tx = data[offset..offset + 32].to_vec();
offset += 32;
let index = u32::from_le_bytes([data[offset], data[offset + 1], data[offset + 2], data[offset + 3]]);
offset += 4;
inputs.push(Input { previous_tx, index: index.try_into().unwrap() });
}

// Deserialize outputs
while offset + 40 <= data.len() {
let recipient = data[offset..offset + 32].to_vec();
offset += 32;
let amount = u64::from_le_bytes([
data[offset], data[offset + 1], data[offset + 2], data[offset + 3],
data[offset + 4], data[offset + 5], data[offset + 6], data[offset + 7],
]);
offset += 8;
outputs.push(Output { recipient, amount });
}

if offset != data.len() {
return Err(TransactionError::new("Invalid data length"));
}

Ok(Self { inputs, outputs })
}
}

0 comments on commit b8a1b81

Please sign in to comment.