qualia_client_core/wallet/
transaction.rs1#[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}