Skip to main content

miden_protocol/note/
note_id.rs

1use core::fmt::Display;
2
3use miden_crypto_derive::WordWrapper;
4
5use super::{NoteDetailsCommitment, NoteMetadata};
6use crate::utils::serde::{
7    ByteReader,
8    ByteWriter,
9    Deserializable,
10    DeserializationError,
11    Serializable,
12};
13use crate::{Hasher, Word, WordError};
14
15// NOTE ID
16// ================================================================================================
17
18/// The unique identifier of a note.
19///
20/// The note ID is computed as:
21///
22/// > hash(NOTE_DETAILS_COMMITMENT || NOTE_METADATA_COMMITMENT)
23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, WordWrapper)]
24pub struct NoteId(Word);
25
26impl NoteId {
27    /// Returns a new [`NoteId`] from the provided details commitment and metadata.
28    pub fn new(details_commitment: NoteDetailsCommitment, metadata: &NoteMetadata) -> Self {
29        Self(Hasher::merge(&[details_commitment.as_word(), metadata.to_commitment()]))
30    }
31}
32
33impl Display for NoteId {
34    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35        write!(f, "{}", self.to_hex())
36    }
37}
38
39impl NoteId {
40    /// Attempts to convert from a hexadecimal string to [NoteId].
41    ///
42    /// Callers must ensure the provided value is an actual [`NoteId`].
43    pub fn try_from_hex(hex_value: &str) -> Result<NoteId, WordError> {
44        Word::try_from(hex_value).map(NoteId::from_raw)
45    }
46}
47
48// SERIALIZATION
49// ================================================================================================
50
51impl Serializable for NoteId {
52    fn write_into<W: ByteWriter>(&self, target: &mut W) {
53        target.write_bytes(&self.0.to_bytes());
54    }
55
56    fn get_size_hint(&self) -> usize {
57        Word::SERIALIZED_SIZE
58    }
59}
60
61impl Deserializable for NoteId {
62    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
63        let id = Word::read_from(source)?;
64        Ok(Self(id))
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use alloc::string::ToString;
71
72    use super::NoteId;
73
74    #[test]
75    fn note_id_try_from_hex() {
76        let note_id_hex = "0xc9d31c82c098e060c9b6e3af2710b3fc5009a1a6f82ef9465f8f35d1f5ba4a80";
77        let note_id = NoteId::try_from_hex(note_id_hex).unwrap();
78
79        assert_eq!(note_id.as_word().to_string(), note_id_hex)
80    }
81}