iota_sdk_types/
object_id.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2025 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use super::Address;
6
7/// An `ObjectId` is a 32-byte identifier used to uniquely identify an object on
8/// the IOTA blockchain.
9///
10/// ## Relationship to Address
11///
12/// [`Address`]es and `ObjectId`s share the same 32-byte addressable space but
13/// are derived leveraging different domain-separator values to ensure,
14/// cryptographically, that there won't be any overlap, e.g. there can't be a
15/// valid `Object` whose `ObjectId` is equal to that of the `Address` of a user
16/// account.
17///
18/// # BCS
19///
20/// An `ObjectId`'s BCS serialized form is defined by the following:
21///
22/// ```text
23/// object-id = 32*OCTET
24/// ```
25#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
28#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
29pub struct ObjectId(Address);
30
31impl ObjectId {
32    pub const LENGTH: usize = Address::LENGTH;
33    pub const ZERO: Self = Self(Address::ZERO);
34    pub const SYSTEM: Self = Self(Address::from_u8(5));
35    pub const CLOCK: Self = Self(Address::from_u8(6));
36
37    /// Generates a new ObjectId from the provided byte array.
38    pub const fn new(bytes: [u8; Self::LENGTH]) -> Self {
39        Self(Address::new(bytes))
40    }
41
42    /// Parse an ObjectId from a hex string.
43    pub fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, super::address::AddressParseError> {
44        Address::from_hex(hex).map(Self)
45    }
46
47    /// Returns the underlying byte array of an ObjectId.
48    pub const fn into_inner(self) -> [u8; Self::LENGTH] {
49        self.0.into_inner()
50    }
51
52    /// Returns a reference to the underlying byte array of an ObjectId.
53    pub const fn inner(&self) -> &[u8; Self::LENGTH] {
54        self.0.inner()
55    }
56
57    /// Returns a slice of bytes of an ObjectId.
58    pub const fn as_bytes(&self) -> &[u8] {
59        self.0.as_bytes()
60    }
61
62    /// Returns the underlying Address of an ObjectId.
63    pub const fn as_address(&self) -> &Address {
64        &self.0
65    }
66}
67
68impl AsRef<[u8]> for ObjectId {
69    fn as_ref(&self) -> &[u8] {
70        self.0.as_ref()
71    }
72}
73
74impl AsRef<[u8; 32]> for ObjectId {
75    fn as_ref(&self) -> &[u8; 32] {
76        self.0.as_ref()
77    }
78}
79
80impl From<ObjectId> for [u8; 32] {
81    fn from(object_id: ObjectId) -> Self {
82        object_id.into_inner()
83    }
84}
85
86impl From<[u8; 32]> for ObjectId {
87    fn from(object_id: [u8; 32]) -> Self {
88        Self::new(object_id)
89    }
90}
91
92impl From<Address> for ObjectId {
93    fn from(value: Address) -> Self {
94        Self(value)
95    }
96}
97
98impl From<ObjectId> for Vec<u8> {
99    fn from(value: ObjectId) -> Self {
100        value.0.into()
101    }
102}
103
104impl std::str::FromStr for ObjectId {
105    type Err = super::address::AddressParseError;
106
107    fn from_str(s: &str) -> Result<Self, Self::Err> {
108        Address::from_str(s).map(Self)
109    }
110}
111
112impl std::fmt::Display for ObjectId {
113    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114        self.0.fmt(f)
115    }
116}