1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use ensicoin_serializer::types::Sha256Result;
use ensicoin_serializer::{Deserialize, Serialize};
use sha2::Digest;

use super::script::OP;
use crate::message::{Message, MessageType};

#[derive(
    Hash, Eq, PartialEq, Clone, Serialize, Deserialize, serde::Serialize, serde::Deserialize,
)]
pub struct Outpoint {
    pub hash: Sha256Result,
    pub index: u32,
}

#[derive(
    Hash, PartialEq, Eq, Serialize, Deserialize, serde::Serialize, serde::Deserialize, Clone,
)]
pub struct TransactionInput {
    pub previous_output: Outpoint,
    pub script: Vec<OP>,
}

#[derive(
    Hash, PartialEq, Eq, Serialize, Deserialize, serde::Serialize, serde::Deserialize, Clone,
)]
pub struct TransactionOutput {
    pub value: u64,
    pub script: Vec<OP>,
}

#[derive(
    Hash, PartialEq, Eq, Serialize, Deserialize, serde::Serialize, serde::Deserialize, Clone,
)]
pub struct Transaction {
    pub version: u32,
    pub flags: Vec<String>,
    pub inputs: Vec<TransactionInput>,
    pub outputs: Vec<TransactionOutput>,
}

impl Transaction {
    pub fn double_hash(&self) -> Sha256Result {
        let bytes = self.serialize();
        let mut hasher = sha2::Sha256::default();
        hasher.input(bytes);
        let first = hasher.result();
        hasher = sha2::Sha256::default();
        hasher.input(first);
        hasher.result()
    }
}

impl Message for Transaction {
    fn message_string() -> [u8; 12] {
        [116, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    }
    fn message_type() -> MessageType {
        MessageType::Transaction
    }
}