use crate::{
ffi,
storage::{StorageValue, TransientStorageValue},
Asm,
};
pub trait Mapping {
const STORAGE_SLOT: i32;
type Key: Asm;
type Value: StorageValue;
#[cfg(not(target_family = "wasm"))]
fn storage_key(key: Self::Key) -> [u8; 32];
fn get(key: Self::Key) -> Self::Value {
load_key(key, Self::STORAGE_SLOT);
Self::Value::sload()
}
fn set(key: Self::Key, value: Self::Value) {
value.push();
load_key(key, Self::STORAGE_SLOT);
unsafe {
ffi::evm::sstore();
}
}
}
pub trait TransientMapping {
const STORAGE_SLOT: i32;
type Key: Asm;
type Value: TransientStorageValue;
#[cfg(not(target_family = "wasm"))]
fn storage_key(key: Self::Key) -> [u8; 32];
fn get(key: Self::Key) -> Self::Value {
load_key(key, Self::STORAGE_SLOT);
Self::Value::tload()
}
fn set(key: Self::Key, value: Self::Value) {
value.push();
load_key(key, Self::STORAGE_SLOT);
unsafe {
ffi::evm::tstore();
}
}
}
fn load_key(key: impl Asm, index: i32) {
unsafe {
ffi::label_reserve_mem_32();
key.push();
ffi::evm::push0();
ffi::evm::mstore();
index.push();
ffi::asm::push_u8(0x20);
ffi::evm::mstore();
ffi::asm::push_u8(0x40);
ffi::evm::push0();
ffi::evm::keccak256();
}
}