Skip to main content

miden_protocol/note/
note_id.rs

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