# Огляд NeuroWASM

> NeuroWASM — середовище виконання смарт-контрактів NeuroChain — інтерпретатор wasmi, облік fuel, host-модуль env, синхронні міжконтрактні виклики, які host-функції працюють, а які заплановані, і мінімальний контракт.

Source: https://docs.nro.world/uk/neurowasm/

**NeuroWASM** — середовище виконання контрактів NeuroChain: WebAssembly, який виконує інтерпретатор `wasmi`, з обліком у fuel і host-функціями, що імпортуються з модуля **`env`**. Його семантика слідує CosmWasm і NEAR, плюс нативні функції **AI host**.

Він не сумісний на рівні бінарників з `wasmd` чи `nearcore` — ті самі ідеї, інший інтерфейс.

## Модель виконання

- **Синхронні виклики.** Контракт, що викликає інший, виконує його до кінця, перш ніж продовжити (як в EVM).
- **Один журнал на транзакцію.** Усі записи сховища, зміни балансів і перекази всього дерева викликів фіксуються разом — або, якщо щось перервалося, жоден з них.
- **Читання власних записів.** Вкладений виклик бачить незафіксовані записи того, хто викликає.
- **Ліміт глибини** — 8 вкладених викликів (`MAX_CALL_DEPTH`).
- **Детермінованість.** Кожен валідатор виконує той самий байткод на тому самому стані й отримує той самий результат; немає годинника, випадковості чи доступу до мережі.

Заплановано пізніше: асинхронні підповідомлення з точкою входу `reply`, потім обіцянки в стилі NEAR і пакети IBC v2.

## Host-функції

Усі імпорти — з `env`. Вказівники й довжини — зміщення `i32` в експортовану контрактом `memory`.

| Область | Працює | Заплановано |
|---------|--------|-------------|
| [Пам'ять](./memory) | `allocate`, `deallocate`, `abort` | — |
| [Сховище](./storage) | `get_storage`, `set_storage` | `remove_storage`, `storage_has`, `storage_usage` |
| [Контекст](./context) | `get_caller`, `get_block_height`, `get_balance`, `get_stake`, `get_stake_at` | `get_self_addr`, `get_signer`, `get_block_time`, `get_shard_id`, `get_attached_deposit`, `gas_remaining` |
| [Банк і події](./bank) | `transfer`, `emit_event`, `set_return` | `log` |
| [Міжконтрактні виклики](./cross-contract) | `call_contract` | `call_contract_with_value` |
| [Криптографія](./crypto) | — | `sha3_256`, `verify_mldsa65`, `addr_validate` |
| [AI host](./ai-host) | — | Читання моделей, сертифікатів, Sentinel, списку довіри й абстракції акаунтів |

Точки входу, які експортує контракт, описано в [Експортах контракту](./exports); ліміти й ціни fuel — у [Газ і ліміти](./gas-limits).

## Мінімальний контракт {#a-minimal-contract}

Лічильник на `no_std` Rust. Він читає виклик, зберігає число в сховищі й повертає його.

```rust
#![no_std]

#[link(wasm_import_module = "env")]
extern "C" {
    fn get_storage(key_ptr: i32, key_len: i32, val_ptr: i32, val_max: i32) -> i32;
    fn set_storage(key_ptr: i32, key_len: i32, val_ptr: i32, val_len: i32);
    fn set_return(ptr: i32, len: i32);
}

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! { core::arch::wasm32::unreachable() }

const KEY: &[u8] = b"count";

fn read_count() -> u64 {
    let mut buf = [0u8; 20];
    let n = unsafe { get_storage(KEY.as_ptr() as i32, KEY.len() as i32, buf.as_mut_ptr() as i32, 20) };
    if n <= 0 { return 0; }
    core::str::from_utf8(&buf[..n as usize]).ok().and_then(|s| s.parse().ok()).unwrap_or(0)
}

#[no_mangle]
pub extern "C" fn call(input_ptr: i32, input_len: i32) {
    let input = unsafe { core::slice::from_raw_parts(input_ptr as *const u8, input_len as usize) };
    let mut n = read_count();
    if input.windows(11).any(|w| w == b"\"increment\"") {
        n += 1;
        let mut out = [0u8; 20];
        let s = fmt_u64(n, &mut out);
        unsafe { set_storage(KEY.as_ptr() as i32, KEY.len() as i32, s.as_ptr() as i32, s.len() as i32) };
    }
    let mut out = [0u8; 20];
    let s = fmt_u64(n, &mut out);
    unsafe { set_return(s.as_ptr() as i32, s.len() as i32) };
}

fn fmt_u64(mut v: u64, buf: &mut [u8; 20]) -> &[u8] {
    let mut i = 20;
    loop { i -= 1; buf[i] = b'0' + (v % 10) as u8; v /= 10; if v == 0 { break; } }
    &buf[i..]
}
```

Викличте його з `{"function":"increment"}`, щоб додати одиницю, або з будь-чим іншим, щоб прочитати. Збирайте й розгортайте, як описано в [Розгортанні контрактів](/uk/build/deploy). Токен NRC-20 у `neurochain/contracts/nrc20` — повний, більший приклад.

Проєктний документ цього інтерфейсу — `docs/neuro-wasm-spec.md` у репозиторії.
