Trait MemoryLike

Source
pub trait MemoryLike {
    // Required methods
    fn fits_memory(&self, slice: MemSlice) -> Result<(), ()>;
    fn view_memory(&self, slice: MemSlice) -> Result<Cow<'_, [u8]>, ()>;
    fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), ()>;
    fn write_memory(&mut self, offset: u64, buffer: &[u8]) -> Result<(), ()>;
}
Expand description

An abstraction over the memory of the smart contract.

Required Methods§

Source

fn fits_memory(&self, slice: MemSlice) -> Result<(), ()>

Returns success if the memory interval is completely inside smart contract’s memory.

You often don’t need to use this method since other methods will perform the check, however it may be necessary to prevent potential denial of service attacks. See Self::read_memory for description.

Source

fn view_memory(&self, slice: MemSlice) -> Result<Cow<'_, [u8]>, ()>

Returns view of the content of the given memory interval.

Not all implementations support borrowing the memory directly. In those cases, the data is copied into a vector.

Source

fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), ()>

Reads the content of the given memory interval.

Returns error if the memory interval isn’t completely inside the smart contract memory.

§Potential denial of service

Note that improper use of this function may lead to denial of service attacks. For example, consider the following function:


fn read_vec(mem: &dyn MemoryLike, slice: MemSlice) -> Result<Vec<u8>, ()> {
    let mut vec = vec![0; slice.len()?];
    mem.read_memory(slice.ptr, &mut vec[..])?;
    Ok(vec)
}

If attacker controls length argument, it may cause attempt at allocation of arbitrarily-large buffer and crash the program. In situations like this, it’s necessary to use Self::fits_memory method to verify that the length is valid. For example:


fn read_vec(mem: &dyn MemoryLike, slice: MemSlice) -> Result<Vec<u8>, ()> {
    mem.fits_memory(slice)?;
    let mut vec = vec![0; slice.len()?];
    mem.read_memory(slice.ptr, &mut vec[..])?;
    Ok(vec)
}
Source

fn write_memory(&mut self, offset: u64, buffer: &[u8]) -> Result<(), ()>

Writes the buffer into the smart contract memory.

Returns error if the memory interval isn’t completely inside the smart contract memory.

Implementors§