sui_verifier_latest/
struct_with_key_verifier.rs1use crate::verification_failure;
10use move_binary_format::file_format::{CompiledModule, SignatureToken};
11use sui_types::{
12 SUI_FRAMEWORK_ADDRESS,
13 error::ExecutionError,
14 fp_ensure,
15 id::{OBJECT_MODULE_NAME, UID_STRUCT_NAME},
16};
17
18pub fn verify_module(module: &CompiledModule) -> Result<(), ExecutionError> {
19 verify_key_structs(module)?;
20 verify_no_key_enums(module)
21}
22
23fn verify_key_structs(module: &CompiledModule) -> Result<(), ExecutionError> {
24 let struct_defs = &module.struct_defs;
25 for def in struct_defs {
26 let handle = module.datatype_handle_at(def.struct_handle);
27 if !handle.abilities.has_key() {
28 continue;
29 }
30 let name = module.identifier_at(handle.name);
31
32 let first_field = match def.field(0) {
34 Some(field) => field,
35 None => {
36 return Err(verification_failure(format!(
37 "First field of struct {} must be 'id', no field found",
38 name
39 )));
40 }
41 };
42 let first_field_name = module.identifier_at(first_field.name).as_str();
43 if first_field_name != "id" {
44 return Err(verification_failure(format!(
45 "First field of struct {} must be 'id', {} found",
46 name, first_field_name
47 )));
48 }
49 let uid_field_type = &first_field.signature.0;
51 let uid_field_type = match uid_field_type {
52 SignatureToken::Datatype(struct_type) => struct_type,
53 _ => {
54 return Err(verification_failure(format!(
55 "First field of struct {} must be of type {}::object::UID, \
56 {:?} type found",
57 name, SUI_FRAMEWORK_ADDRESS, uid_field_type
58 )));
59 }
60 };
61 let uid_type_struct = module.datatype_handle_at(*uid_field_type);
63 let uid_type_struct_name = module.identifier_at(uid_type_struct.name);
64 let uid_type_module = module.module_handle_at(uid_type_struct.module);
65 let uid_type_module_address = module.address_identifier_at(uid_type_module.address);
66 let uid_type_module_name = module.identifier_at(uid_type_module.name);
67 fp_ensure!(
68 uid_type_struct_name == UID_STRUCT_NAME
69 && uid_type_module_address == &SUI_FRAMEWORK_ADDRESS
70 && uid_type_module_name == OBJECT_MODULE_NAME,
71 verification_failure(format!(
72 "First field of struct {} must be of type {}::object::UID, \
73 {}::{}::{} type found",
74 name,
75 SUI_FRAMEWORK_ADDRESS,
76 uid_type_module_address,
77 uid_type_module_name,
78 uid_type_struct_name
79 ))
80 );
81 }
82 Ok(())
83}
84
85fn verify_no_key_enums(module: &CompiledModule) -> Result<(), ExecutionError> {
86 for def in &module.enum_defs {
87 let handle = module.datatype_handle_at(def.enum_handle);
88 if handle.abilities.has_key() {
89 return Err(verification_failure(format!(
90 "Enum {} cannot have the 'key' ability. Enums cannot have the 'key' ability.",
91 module.identifier_at(handle.name)
92 )));
93 }
94 }
95 Ok(())
96}