---
title: "VM Layer"
path: "/contents/tech/core-protocols/vm-layer"
version: "2.0.0"
author: "Hydrate"
createdAt: "2026-05-03T09:53:55.560Z"
updatedAt: "2026-08-06T23:11:04.036Z"
---

# VM Layer

<Infobox>
| Engine – VM |
| Engine Layer |
| Scrypto VM (WebAssembly), Native VM (Rust) |
| `wasmi` interpreter |
| V1_2 (Cuttlefish) |
| `radix-engine/src/vm` |
| [radixdlt-scrypto](https://github.com/radixdlt/radixdlt-scrypto) |
</Infobox>

## Introduction

The VM layer of the [Radix Engine](/contents/tech/core-protocols/radix-engine) executes blueprint code. Two virtual machines coexist: the **Scrypto VM**, which runs developer-authored WebAssembly compiled from [Scrypto](/contents/tech/core-protocols/scrypto-programming-language), and the **Native VM**, which runs the engine's built-in blueprints — Account, Package, ConsensusManager, the pools and the resource package — as compiled Rust. Both implement the same invocation contract, so the [system layer](/contents/tech/core-protocols/system-layer) above them calls a native blueprint and a WASM blueprint the same way, and a Scrypto component can hold a vault or call a pool without knowing which side of the boundary it is talking to.

Sitting between the [kernel](/contents/tech/core-protocols/kernel-layer) and the [application layer](/contents/tech/core-protocols/application-layer), this is the layer where determinism has to be manufactured: the same transaction must produce the same result and consume the same fee on every node, this year and in five years, which constrains what a virtual machine on a public ledger is allowed to be.

## The Scrypto VM

Developer code reaches the network as WebAssembly, and the engine runs it on [`wasmi`](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/Cargo.toml), an interpreter targeting the WebAssembly MVP. An interpreter rather than a JIT compiler is a deliberate trade: predictable, identical execution on every node matters more here than raw speed, and a compiler's output can vary with the host.

Uploaded WASM passes three gates before it ever runs. It is **validated** with `wasmparser`, rejecting the module outright if it uses features outside the supported subset. It is **instrumented** with [`radix-wasm-instrument`](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/Cargo.toml), which injects metering calls so that execution charges by the instruction rather than by wall-clock time — the per-instruction costs are a table of [weights](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/vm/wasm/weights.rs), and memory growth carries its own charge. And it is **bounded**: [`WasmValidatorConfigV1`](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/vm/wasm/wasm_validator_config.rs) caps the call stack at 1,024 frames, so recursion terminates as a clean transaction failure instead of exhausting a validator's memory.

Metering is why a Radix transaction's fee is a property of the transaction rather than of the node that ran it. The instrumented module calls back into the engine through a host function literally named `gas`, decrementing the transaction's cost-unit budget as it goes; run out and execution aborts and the state changes are discarded.

## The Native VM

The engine's own blueprints do not go through WASM at all. The [Native VM](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/vm/native_vm.rs) dispatches on package address straight into compiled Rust — Account, Identity, Package, ConsensusManager, AccessController, Locker, TransactionProcessor, TransactionTracker, the pool package and the [resource](/contents/tech/core-concepts/resources) package, plus the object modules for [metadata](/contents/tech/core-concepts/metadata-module), [role assignment](/contents/tech/core-concepts/role-assignment-module) and [royalties](/contents/tech/core-concepts/component-royalties). These are the pieces every transaction touches, and running them natively is what keeps the cost of a transfer down to the cost of a transfer.

It is also where [protocol updates](/contents/tech/releases/protocol-updates) land. Because native code cannot be uploaded, changing a native blueprint means shipping a new node version — so the source carries the versions side by side as explicit extensions: `AccountBlueprintBottlenoseExtension` and `AccountBlueprintCuttlefishExtension`, `WorktopBlueprintCuttlefishExtension`, `ConsensusManagerSecondsPrecisionNativeCode`, an `AccessController` v1 and v2. Old transactions keep resolving against the behaviour that was current when they were committed, which is what makes the ledger replayable from genesis after a protocol update rather than merely consistent going forward.

## The VM Boundary

WASM in the Scrypto VM cannot touch ledger state directly. Every effect goes through a fixed, named set of host functions defined in [`vm/wasm/constants.rs`](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/vm/wasm/constants.rs), and the list is short enough to read in a minute: `blueprint_call`, `object_new`, `object_globalize`, `object_call`, `actor_open_field`, `actor_emit_event`, `kv_store_new`, `kv_entry_read`, `field_entry_write`, `address_allocate`, `gas`, and a handful of siblings.

That narrowness is the security argument for the whole design. A blueprint cannot open a socket, read a clock, generate an unseeded random number or reach into another component's substates, because no host function exposes any of it — the sources of non-determinism that other execution environments have to discipline by convention are simply not reachable. It is also why [asset-oriented](/contents/tech/core-concepts/asset-oriented-programming) guarantees hold: a bucket of resource moves by calling into the engine, and the engine enforces conservation at the boundary rather than trusting the blueprint that asked.

## Versioning

The Scrypto VM itself is versioned, in a short ladder tied to the network's protocol updates. [`ScryptoVmVersion`](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/vm/versions.rs) runs `V1_0` at [Babylon](/contents/tech/releases/radix-mainnet-babylon) genesis, `V1_1` from Anemone — which introduced the first set of cryptographic utility host functions — and `V1_2` from Cuttlefish, which added the second. `V1_2` is the latest, and the version in force is carried in a VM boot substate on the ledger rather than compiled into the node as a constant.

Reading the active version from state, instead of assuming it, is what lets a node built today re-execute a transaction from 2023 under the VM that was live at the time. It is the same discipline as the native blueprint extensions, applied to the WASM side.

## What Xi'an Changes

This layer is the one the [Hyperscale](/contents/tech/research/hyperscale-rs) programme is replacing. A sharded network needs a transaction's full data requirements to resolve before execution, so that conflicts can be analysed without running anything, and the Radix Engine's state access is — on the lead developer's assessment — too loose for that. The decision to build a purpose-built VM rather than retrofit the existing one was confirmed on 1 August 2026, and belongs to [Xi'an](/contents/tech/releases/radix-mainnet-xian) rather than to mainnet as deployed, which continues to run everything described above.

What that means for existing developers was stated two days later: ["Scrypto is literally just a couple of Rust macros. Not particularly hard to hit parity"](https://t.me/hyperscale_rs/10414), with manifest, resources, subintents and badges kept as-is and the change confined to ["the lower layers like state, locks, parallelism"](https://t.me/hyperscale_rs/10414). Read against this page, that is a precise claim: the VM boundary and the native blueprint set survive; the interpreter, the metering strategy and the substate access underneath them do not. No migration has been scheduled.

## External Links

- [radix-engine/src/vm — both virtual machines](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/vm)

- [Host function names exposed to WASM](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/vm/wasm/constants.rs)

- [ScryptoVmVersion ladder](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/vm/versions.rs)

- [WASM validation and metering configuration](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/vm/wasm/wasm_validator_config.rs)

- [Scrypto compilation pipeline](https://github.com/radixdlt/radixdlt-scrypto/tree/main/scrypto-compiler)