Skip to content

Instantly share code, notes, and snippets.

@milancermak
Created March 31, 2023 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save milancermak/ae7712d702415af260d6e857e8efc01c to your computer and use it in GitHub Desktop.
Save milancermak/ae7712d702415af260d6e857e8efc01c to your computer and use it in GitHub Desktop.
StorageAccess with embedded structs
use starknet::StorageAccess;
use starknet::StorageBaseAddress;
use starknet::SyscallResult;
use starknet::storage_read_syscall;
use starknet::storage_write_syscall;
use starknet::storage_address_from_base_and_offset;
use traits::Into;
use traits::TryInto;
use option::OptionTrait;
#[derive(Copy, Drop, Serde)]
struct Pos2D{
x: u16,
y: u16
}
#[derive(Copy, Drop, Serde)]
struct Army {
position: Pos2D,
health: u32
}
//
// Pos2D StorageAccess
//
impl Pos2DStorageAccess of StorageAccess::<Pos2D> {
fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult::<Pos2D> {
Result::Ok(
Pos2D {
x: storage_read_syscall(
address_domain,
storage_address_from_base_and_offset(base, 0_u8)
)?.try_into().unwrap(),
y: storage_read_syscall(
address_domain,
storage_address_from_base_and_offset(base, 1_u8)
)?.try_into().unwrap(),
}
)
}
fn write(address_domain: u32, base: StorageBaseAddress, value: Pos2D) -> SyscallResult::<()> {
storage_write_syscall(
address_domain,
storage_address_from_base_and_offset(base, 0_u8),
value.x.into()
)?;
storage_write_syscall(
address_domain,
storage_address_from_base_and_offset(base, 1_u8),
value.y.into()
)
}
}
//
// Army StorageAccess
//
impl ArmyStorageAccess of StorageAccess::<Army> {
fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult::<Army> {
let pos: Pos2D = StorageAccess::<Pos2D>::read(address_domain, base)?;
Result::Ok(
Army {
position: pos,
health: storage_read_syscall(
address_domain,
storage_address_from_base_and_offset(base, 2_u8)
)?.try_into().unwrap()
}
)
}
fn write(address_domain: u32, base: StorageBaseAddress, value: Army) -> SyscallResult::<()> {
StorageAccess::<Pos2D>::write(address_domain, base, value.position)?;
storage_write_syscall(
address_domain,
storage_address_from_base_and_offset(base, 2_u8),
value.health.into()
)
}
}
#[contract]
mod Game {
use super::Pos2D;
use super::Army;
struct Storage {
army: Army
}
fn update_army(health: u32, x: u16, y: u16) {
let position = Pos2D { x, y };
army::write(Army { health, position });
}
fn get_army() -> Army {
army::read()
}
}
#[test]
#[available_gas(1000000)]
fn test_storage() {
let a = Game::get_army();
assert(a.health == 0_u32, 'nope');
assert(a.position.x == 0_u16, 'nope');
assert(a.position.y == 0_u16, 'nope');
Game::update_army(100_u32, 6_u16, 20_u16);
let a = Game::get_army();
assert(a.health == 100_u32, 'nope');
assert(a.position.x == 6_u16, 'nope');
assert(a.position.y == 20_u16, 'nope');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment