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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use miden_crypto::{
    utils::{ByteReader, ByteWriter, Deserializable, Serializable},
    Word,
};
use vm_processor::DeserializationError;

use super::{NoteAssets, NoteId, NoteInputs, NoteRecipient, NoteScript, Nullifier};

// NOTE DETAILS
// ================================================================================================

/// Details of a note consisting of assets, script, inputs, and a serial number.
///
/// See [super::Note] for more details.
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct NoteDetails {
    assets: NoteAssets,
    recipient: NoteRecipient,
}

impl NoteDetails {
    // CONSTRUCTOR
    // --------------------------------------------------------------------------------------------

    /// Returns a new note created with the specified parameters.
    pub fn new(assets: NoteAssets, recipient: NoteRecipient) -> Self {
        Self { assets, recipient }
    }

    // PUBLIC ACCESSORS
    // --------------------------------------------------------------------------------------------

    /// Returns the note's unique identifier.
    ///
    /// This value is both an unique identifier and a commitment to the note.
    pub fn id(&self) -> NoteId {
        NoteId::from(self)
    }

    /// Returns the note's assets.
    pub fn assets(&self) -> &NoteAssets {
        &self.assets
    }

    /// Returns the note's recipient serial_num, the secret required to consume the note.
    pub fn serial_num(&self) -> Word {
        self.recipient.serial_num()
    }

    /// Returns the note's recipient script which locks the assets of this note.
    pub fn script(&self) -> &NoteScript {
        self.recipient.script()
    }

    /// Returns the note's recipient inputs which customizes the script's behavior.
    pub fn inputs(&self) -> &NoteInputs {
        self.recipient.inputs()
    }

    /// Returns the note's recipient.
    pub fn recipient(&self) -> &NoteRecipient {
        &self.recipient
    }

    /// Returns the note's nullifier.
    ///
    /// This is public data, used to prevent double spend.
    pub fn nullifier(&self) -> Nullifier {
        Nullifier::from(self)
    }

    /// Decomposes note details into underlying assets and recipient.
    pub fn into_parts(self) -> (NoteAssets, NoteRecipient) {
        (self.assets, self.recipient)
    }
}

// SERIALIZATION
// ================================================================================================

impl Serializable for NoteDetails {
    fn write_into<W: ByteWriter>(&self, target: &mut W) {
        let Self { assets, recipient } = self;

        assets.write_into(target);
        recipient.write_into(target);
    }
}

impl Deserializable for NoteDetails {
    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
        let assets = NoteAssets::read_from(source)?;
        let recipient = NoteRecipient::read_from(source)?;
        Ok(Self::new(assets, recipient))
    }
}