zink/storage/
dkmapping.rs1use crate::{asm, storage::Value};
4
5pub trait DoubleKeyMapping {
7 const STORAGE_SLOT: i32;
8
9 type Key1: Value;
10 type Key2: Value;
11 type Value: Value;
12
13 #[cfg(not(target_family = "wasm"))]
14 fn storage_key(key1: Self::Key1, key2: Self::Key2) -> [u8; 32];
15
16 #[inline(always)]
18 fn get(key1: Self::Key1, key2: Self::Key2) -> Self::Value {
19 load_double_key(key1, key2, Self::STORAGE_SLOT);
20 Self::Value::sload()
21 }
22
23 #[inline(always)]
25 fn set(key1: Self::Key1, key2: Self::Key2, value: Self::Value) {
26 value.push();
27 load_double_key(key1, key2, Self::STORAGE_SLOT);
28 unsafe {
29 asm::evm::sstore();
30 }
31 }
32}
33
34pub trait DoubleKeyTransientMapping {
36 const STORAGE_SLOT: i32;
37
38 type Key1: Value;
39 type Key2: Value;
40 type Value: Value;
41
42 #[cfg(not(target_family = "wasm"))]
43 fn storage_key(key1: Self::Key1, key2: Self::Key2) -> [u8; 32];
44
45 #[inline(always)]
47 fn get(key1: Self::Key1, key2: Self::Key2) -> Self::Value {
48 load_double_key(key1, key2, Self::STORAGE_SLOT);
49 Self::Value::tload()
50 }
51
52 #[inline(always)]
54 fn set(key1: Self::Key1, key2: Self::Key2, value: Self::Value) {
55 value.push();
56 load_double_key(key1, key2, Self::STORAGE_SLOT);
57 unsafe {
58 asm::evm::tstore();
59 }
60 }
61}
62
63#[inline(always)]
65pub fn load_double_key(key1: impl Value, key2: impl Value, index: i32) {
66 unsafe {
67 asm::label_reserve_mem_64();
68
69 key1.push();
71 asm::evm::push0();
72 asm::evm::mstore();
73
74 index.push();
76 asm::ext::push_u8(0x20);
77 asm::evm::mstore();
78
79 asm::ext::push_u8(0x40);
81 asm::evm::push0();
82 asm::evm::keccak256();
83
84 asm::evm::push0();
86 asm::evm::mstore();
87
88 key2.push();
90 asm::ext::push_u8(0x20);
91 asm::evm::mstore();
92
93 asm::ext::push_u8(0x40);
95 asm::evm::push0();
96 asm::evm::keccak256();
97 }
98}