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