wevm-core 0.4.1

Waves Enterprise Virtual Machine for WASM smart-contracts
Documentation
use crate::{error::RuntimeError, node::Node, runtime::Runtime};
use blake2::{digest::consts::U32, Blake2b, Digest};
use sha2::Sha256;
use sha3::Keccak256;
use wasmi::Caller;

pub fn fast_hash(
    offset_bytes: u32,
    length_bytes: u32,
    mut caller: Caller<Runtime>,
) -> (i32, u32, u32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0, 0),
    };
    let offset_memory = ctx.heap_base() as usize;

    let bytes = &memory[offset_bytes as usize..offset_bytes as usize + length_bytes as usize];

    match ctx.vm.fast_hash(bytes) {
        Ok(result) => crate::env::write_memory(ctx, memory, offset_memory, result),
        Err(error) => (error.as_i32(), 0, 0),
    }
}

pub fn secure_hash(
    offset_bytes: u32,
    length_bytes: u32,
    mut caller: Caller<Runtime>,
) -> (i32, u32, u32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0, 0),
    };
    let offset_memory = ctx.heap_base() as usize;

    let bytes = &memory[offset_bytes as usize..offset_bytes as usize + length_bytes as usize];

    match ctx.vm.secure_hash(bytes) {
        Ok(result) => crate::env::write_memory(ctx, memory, offset_memory, result),
        Err(error) => (error.as_i32(), 0, 0),
    }
}

pub fn blake2b256(
    offset_bytes: u32,
    length_bytes: u32,
    mut caller: Caller<Runtime>,
) -> (i32, u32, u32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0, 0),
    };
    let offset_memory = ctx.heap_base() as usize;

    let mut hasher: Blake2b<U32> = Blake2b::new();
    hasher.update(&memory[offset_bytes as usize..offset_bytes as usize + length_bytes as usize]);

    crate::env::write_memory(ctx, memory, offset_memory, hasher.finalize().to_vec())
}

pub fn keccak256(
    offset_bytes: u32,
    length_bytes: u32,
    mut caller: Caller<Runtime>,
) -> (i32, u32, u32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0, 0),
    };
    let offset_memory = ctx.heap_base() as usize;

    let mut hasher = Keccak256::new();
    hasher.update(&memory[offset_bytes as usize..offset_bytes as usize + length_bytes as usize]);

    crate::env::write_memory(ctx, memory, offset_memory, hasher.finalize().to_vec())
}

pub fn sha256(
    offset_bytes: u32,
    length_bytes: u32,
    mut caller: Caller<Runtime>,
) -> (i32, u32, u32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0, 0),
    };
    let offset_memory = ctx.heap_base() as usize;

    let mut hasher = Sha256::new();
    hasher.update(&memory[offset_bytes as usize..offset_bytes as usize + length_bytes as usize]);

    crate::env::write_memory(ctx, memory, offset_memory, hasher.finalize().to_vec())
}

pub fn sig_verify(
    offset_message: u32,
    length_message: u32,
    offset_signature: u32,
    length_signature: u32,
    offset_public_key: u32,
    length_public_key: u32,
    mut caller: Caller<Runtime>,
) -> (i32, i32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0),
    };

    let message =
        &memory[offset_message as usize..offset_message as usize + length_message as usize];
    let signature =
        &memory[offset_signature as usize..offset_signature as usize + length_signature as usize];
    let public_key = &memory
        [offset_public_key as usize..offset_public_key as usize + length_public_key as usize];

    match ctx.vm.sig_verify(message, signature, public_key) {
        Ok(result) => (0, result as i32),
        Err(error) => (error.as_i32(), 0),
    }
}