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