iota_types/
derived_object.rs1use iota_sdk_types::{Identifier, ObjectId, StructTag, TypeTag};
6
7use crate::{base_types::IotaAddress, dynamic_field};
8
9pub const DERIVED_OBJECT_MODULE_NAME: Identifier = Identifier::from_static("derived_object");
10pub const DERIVED_OBJECT_STRUCT_NAME: Identifier = Identifier::from_static("DerivedObjectKey");
11
12pub fn derive_object_id<T>(
17 parent: T,
18 key_type_tag: &TypeTag,
19 key_bytes: &[u8],
20) -> Result<ObjectId, bcs::Error>
21where
22 T: Into<IotaAddress>,
23{
24 let parent_address = parent.into();
25
26 let wrapper_type_tag = TypeTag::Struct(Box::new(StructTag::new(
28 IotaAddress::FRAMEWORK,
29 DERIVED_OBJECT_MODULE_NAME,
30 DERIVED_OBJECT_STRUCT_NAME,
31 vec![key_type_tag.clone()],
32 )));
33
34 dynamic_field::derive_dynamic_field_id(parent_address, &wrapper_type_tag, key_bytes)
35}
36
37#[cfg(test)]
38mod tests {
39 use std::str::FromStr;
40
41 use serde::Serialize;
42
43 use super::*;
44
45 #[derive(Serialize)]
46 struct DemoStruct {
47 value: u64,
48 }
49
50 #[derive(Serialize)]
51 struct GenericStruct<T> {
52 value: T,
53 }
54
55 #[test]
58 fn test_derive_object_snapshot() {
59 let key_bytes = bcs::to_bytes("foo".as_bytes()).unwrap();
61 let key_type_tag = TypeTag::Vector(Box::new(TypeTag::U8));
62
63 let id = derive_object_id(
64 ObjectId::from_str("0x2").unwrap(),
65 &key_type_tag,
66 &key_bytes,
67 )
68 .unwrap();
69
70 assert_eq!(
71 id,
72 ObjectId::from_str(
73 "0xa2b411aa9588c398d8e3bc97dddbdd430b5ded7f81545d05e33916c3ca0f30c3"
74 )
75 .unwrap()
76 );
77 }
78
79 #[test]
80 fn test_derive_object_with_struct_key_snapshot() {
81 let key = DemoStruct { value: 1 };
82 let key_value = bcs::to_bytes(&key).unwrap();
83
84 let id = derive_object_id(
85 ObjectId::from_str("0x2").unwrap(),
86 &TypeTag::Struct(Box::new(StructTag::new(
87 IotaAddress::FRAMEWORK,
88 Identifier::from_static("derived_object_tests"),
89 Identifier::from_static("DemoStruct"),
90 vec![],
91 ))),
92 &key_value,
93 )
94 .unwrap();
95
96 assert_eq!(
97 id,
98 ObjectId::from_str(
99 "0x20c58d8790a5d2214c159c23f18a5fdc347211e511186353e785ad543abcea6b"
100 )
101 .unwrap()
102 );
103 }
104
105 #[test]
106 fn test_derive_object_with_generic_struct_key_snapshot() {
107 let key = GenericStruct::<u64> { value: 1 };
108 let key_value = bcs::to_bytes(&key).unwrap();
109
110 let id = derive_object_id(
111 ObjectId::from_str("0x2").unwrap(),
112 &TypeTag::Struct(Box::new(StructTag::new(
113 IotaAddress::FRAMEWORK,
114 Identifier::from_static("derived_object_tests"),
115 Identifier::from_static("GenericStruct"),
116 vec![TypeTag::U64],
117 ))),
118 &key_value,
119 )
120 .unwrap();
121
122 assert_eq!(
123 id,
124 ObjectId::from_str(
125 "0xb497b8dcf1e297ae5fa69c040e4a08ef8240d5373bbc9d6b686ffbd7dfe04cbe"
126 )
127 .unwrap()
128 );
129 }
130}