neo_solidity/cli/bytecode/bytecode_helpers/storage/
mapping.rs1fn emit_serialize_key(
2 bytecode: &mut Vec<u8>,
3 _key_type: &ValueType,
4 use_callt: bool,
5 token_patches: &mut Vec<MethodTokenPatch>,
6) {
7 emit_native_contract_call(
8 bytecode,
9 ir::NativeContract::StdLib,
10 "serialize",
11 1,
12 use_callt,
13 token_patches,
14 );
15}
16
17fn emit_mapping_slot(
18 bytecode: &mut Vec<u8>,
19 module: &ir::Module,
20 state_index: usize,
21 key_types: &[ValueType],
22 use_callt: bool,
23 token_patches: &mut Vec<MethodTokenPatch>,
24) {
25 let base_slot = module
26 .state_variables
27 .get(state_index)
28 .map(|state| state.storage_key.clone())
29 .unwrap_or_else(|| vec![0u8; 32]);
30
31 push_data(bytecode, &base_slot);
32
33 for key_type in key_types {
34 bytecode.push(0x50); emit_serialize_key(bytecode, key_type, use_callt, token_patches);
36 bytecode.push(0x50); bytecode.push(0x8B); emit_native_contract_call(
39 bytecode,
40 ir::NativeContract::CryptoLib,
41 "keccak256",
42 1,
43 use_callt,
44 token_patches,
45 );
46 }
47}
48
49fn emit_struct_field_slot(
50 bytecode: &mut Vec<u8>,
51 module: &ir::Module,
52 state_index: usize,
53 key_types: &[ValueType],
54 field_keys: &[[u8; 32]],
55 use_callt: bool,
56 token_patches: &mut Vec<MethodTokenPatch>,
57) {
58 emit_mapping_slot(
59 bytecode,
60 module,
61 state_index,
62 key_types,
63 use_callt,
64 token_patches,
65 );
66 for field_key in field_keys {
67 push_data(bytecode, field_key);
68 bytecode.push(0x50); bytecode.push(0x8B); emit_native_contract_call(
71 bytecode,
72 ir::NativeContract::CryptoLib,
73 "keccak256",
74 1,
75 use_callt,
76 token_patches,
77 );
78 }
79}
80
81fn emit_load_mapping(
82 bytecode: &mut Vec<u8>,
83 module: &ir::Module,
84 state_index: usize,
85 key_types: &[ValueType],
86 use_callt: bool,
87 token_patches: &mut Vec<MethodTokenPatch>,
88) {
89 emit_mapping_slot(
90 bytecode,
91 module,
92 state_index,
93 key_types,
94 use_callt,
95 token_patches,
96 );
97 emit_syscall(bytecode, "System.Storage.GetContext");
98 emit_syscall(bytecode, "System.Storage.Get");
99 if let Some(ir::StateVariable {
100 ty: ValueType::Mapping { value, .. },
101 ..
102 }) = module.state_variables.get(state_index)
103 {
104 emit_coerce_storage_value(bytecode, value);
105 }
106}
107
108fn emit_store_mapping(
109 bytecode: &mut Vec<u8>,
110 module: &ir::Module,
111 state_index: usize,
112 key_types: &[ValueType],
113 use_callt: bool,
114 token_patches: &mut Vec<MethodTokenPatch>,
115) {
116 emit_mapping_slot(
117 bytecode,
118 module,
119 state_index,
120 key_types,
121 use_callt,
122 token_patches,
123 );
124 emit_syscall(bytecode, "System.Storage.GetContext");
125 emit_syscall(bytecode, "System.Storage.Put");
126}