Skip to main content

qualia_client_core/wallet/
transaction.rs

1#[derive(Debug, Clone)]
2pub struct TxIn {
3    pub prev_txid: String,
4    pub prev_out_idx: u32,
5    pub signature_script: Vec<u8>,
6    pub sequence: u32,
7}
8
9#[derive(Debug, Clone)]
10pub struct TxOut {
11    pub value: u64,
12    pub pk_script: Vec<u8>,
13}
14
15#[derive(Debug, Clone)]
16pub struct Transaction {
17    pub version: i32,
18    pub inputs: Vec<TxIn>,
19    pub outputs: Vec<TxOut>,
20    pub lock_time: u32,
21}
22
23impl Transaction {
24    pub fn new() -> Self {
25        Self {
26            version: 1,
27            inputs: Vec::new(),
28            outputs: Vec::new(),
29            lock_time: 0,
30        }
31    }
32
33    pub fn serialize(&self) -> Vec<u8> {
34        let mut buf = Vec::new();
35
36        buf.extend_from_slice(&self.version.to_le_bytes());
37
38        buf.extend_from_slice(&encode_varint(self.inputs.len() as u64));
39        for input in &self.inputs {
40            let mut txid_bytes = hex::decode(&input.prev_txid).unwrap_or_else(|_| vec![0; 32]);
41            txid_bytes.reverse();
42            buf.extend_from_slice(&txid_bytes);
43
44            buf.extend_from_slice(&input.prev_out_idx.to_le_bytes());
45
46            buf.extend_from_slice(&encode_varint(input.signature_script.len() as u64));
47            buf.extend_from_slice(&input.signature_script);
48
49            buf.extend_from_slice(&input.sequence.to_le_bytes());
50        }
51
52        buf.extend_from_slice(&encode_varint(self.outputs.len() as u64));
53        for output in &self.outputs {
54            buf.extend_from_slice(&output.value.to_le_bytes());
55            buf.extend_from_slice(&encode_varint(output.pk_script.len() as u64));
56            buf.extend_from_slice(&output.pk_script);
57        }
58
59        buf.extend_from_slice(&self.lock_time.to_le_bytes());
60
61        buf
62    }
63}
64
65pub fn encode_varint(val: u64) -> Vec<u8> {
66    if val < 0xfd {
67        vec![val as u8]
68    } else if val <= 0xffff {
69        let mut res = vec![0xfd];
70        res.extend_from_slice(&(val as u16).to_le_bytes());
71        res
72    } else if val <= 0xffffffff {
73        let mut res = vec![0xfe];
74        res.extend_from_slice(&(val as u32).to_le_bytes());
75        res
76    } else {
77        let mut res = vec![0xff];
78        res.extend_from_slice(&val.to_le_bytes());
79        res
80    }
81}