zink/storage/
dkmapping.rsuse crate::{
ffi,
storage::{StorageValue, TransientStorageValue},
Asm,
};
pub trait DoubleKeyMapping {
const STORAGE_SLOT: i32;
type Key1: Asm;
type Key2: Asm;
type Value: StorageValue;
#[cfg(not(target_family = "wasm"))]
fn storage_key(key1: Self::Key1, key2: Self::Key2) -> [u8; 32];
#[inline(always)]
fn get(key1: Self::Key1, key2: Self::Key2) -> Self::Value {
load_double_key(key1, key2, Self::STORAGE_SLOT);
Self::Value::sload()
}
#[inline(always)]
fn set(key1: Self::Key1, key2: Self::Key2, value: Self::Value) {
value.push();
load_double_key(key1, key2, Self::STORAGE_SLOT);
unsafe {
ffi::evm::sstore();
}
}
}
pub trait DoubleKeyTransientMapping {
const STORAGE_SLOT: i32;
type Key1: Asm;
type Key2: Asm;
type Value: TransientStorageValue;
#[cfg(not(target_family = "wasm"))]
fn storage_key(key1: Self::Key1, key2: Self::Key2) -> [u8; 32];
#[inline(always)]
fn get(key1: Self::Key1, key2: Self::Key2) -> Self::Value {
load_double_key(key1, key2, Self::STORAGE_SLOT);
Self::Value::tload()
}
#[inline(always)]
fn set(key1: Self::Key1, key2: Self::Key2, value: Self::Value) {
value.push();
load_double_key(key1, key2, Self::STORAGE_SLOT);
unsafe {
ffi::evm::tstore();
}
}
}
#[inline(always)]
fn load_double_key(key1: impl Asm, key2: impl Asm, index: i32) {
unsafe {
ffi::label_reserve_mem_64();
key1.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();
ffi::evm::push0();
ffi::evm::mstore();
key2.push();
ffi::asm::push_u8(0x20);
ffi::evm::mstore();
ffi::asm::push_u8(0x40);
ffi::evm::push0();
ffi::evm::keccak256();
}
}