zink/storage/
mapping.rs

1//! Storage Mapping
2
3use crate::{asm, storage::Value};
4
5/// Storage mapping interface
6pub trait Mapping {
7    const STORAGE_SLOT: i32;
8
9    type Key: Value;
10    type Value: Value;
11
12    #[cfg(not(target_family = "wasm"))]
13    fn storage_key(key: Self::Key) -> [u8; 32];
14
15    /// Get value from storage key.
16    fn get(key: Self::Key) -> Self::Value {
17        load_key(key, Self::STORAGE_SLOT);
18        Self::Value::sload()
19    }
20
21    /// Set key and value
22    fn set(key: Self::Key, value: Self::Value) {
23        value.push();
24        load_key(key, Self::STORAGE_SLOT);
25        unsafe {
26            asm::evm::sstore();
27        }
28    }
29}
30
31/// Transient storage mapping interface
32pub trait TransientMapping {
33    const STORAGE_SLOT: i32;
34
35    type Key: Value;
36    type Value: Value;
37
38    #[cfg(not(target_family = "wasm"))]
39    fn storage_key(key: Self::Key) -> [u8; 32];
40
41    /// Get value from transient storage key.
42    fn get(key: Self::Key) -> Self::Value {
43        load_key(key, Self::STORAGE_SLOT);
44        Self::Value::tload()
45    }
46
47    /// Set key and value in transient storage
48    fn set(key: Self::Key, value: Self::Value) {
49        value.push();
50        load_key(key, Self::STORAGE_SLOT);
51
52        unsafe {
53            asm::evm::tstore();
54        }
55    }
56}
57
58/// Load storage key to stack
59pub fn load_key(key: impl Value, index: i32) {
60    unsafe {
61        asm::label_reserve_mem_32();
62
63        // write key to memory
64        key.push();
65        asm::evm::push0();
66        asm::evm::mstore();
67
68        // write index to memory
69        index.push();
70        asm::ext::push_u8(0x20);
71        asm::evm::mstore();
72
73        // hash key
74        asm::ext::push_u8(0x40);
75        asm::evm::push0();
76        asm::evm::keccak256();
77    }
78}