---
title: "System Layer"
url: "https://radix-wiki.miow.me/contents/tech/core-protocols/system-layer"
updated: 2026-10-03
description: "The system layer implements the engine's high-level abstractions – objects, blueprints, packages, modules (Metadata, Royalty, Role Assignment), and the…"
---

# System Layer

| Layer | Engine – System |
| --- | --- |
| Type | Engine Layer |
| Defined in | `radix-engine, radix-engine-interface` |
| Source | [radixdlt-scrypto](https://github.com/radixdlt/radixdlt-scrypto) |
| System version | `V5` (Eagle Ray, 11 September 2026) |

## Introduction

The system layer implements the engine's high-level abstractions – objects, [blueprints](/contents/tech/core-concepts/blueprints-and-packages), packages, modules (Metadata, Royalty, Role Assignment), and the [resource](/contents/tech/core-concepts/resources) model – on top of the lower-level kernel. It is the layer at which application code interacts with the engine and where [access rules](/contents/tech/core-concepts/access-rules-and-auth-zones) are enforced. Type definitions for this layer live in `radix-engine-interface`.

Unlike the [kernel](/contents/tech/core-protocols/kernel-layer), this layer is versioned: which rules it applies depends on a `SystemVersion` the engine reads from ledger state before every transaction, and advancing that version is what a [protocol update](/contents/tech/releases/protocol-updates) does. Mainnet has stood at `V5` since Eagle Ray on 11 September 2026.

## What the System Layer Provides

The system layer’s surface to running blueprint code is the set of API traits in [`radix-engine-interface/src/api`](https://github.com/radixdlt/radixdlt-scrypto/tree/main/radix-engine-interface/src/api), implemented by [`radix-engine/src/system`](https://github.com/radixdlt/radixdlt-scrypto/tree/main/radix-engine/src/system). They divide along what a call is addressing. `actor_api` covers the calling actor itself; `object_api` creates, invokes and drops objects; `field_api` reads and writes an object’s fields; `key_value_store_api` and `key_value_entry_api` handle owned key-value state, with `actor_index_api` and `actor_sorted_index_api` for the indexed and sorted collections the [consensus manager](/contents/tech/core-concepts/consensus-manager) and pools rely on; `blueprint_api` exposes package and blueprint type information; and `costing_api`, `transaction_runtime_api` and `execution_trace_api` reach the metering, transaction-runtime and tracing facilities. A blueprint never touches the [kernel](/contents/tech/core-protocols/kernel-layer) directly – every one of these calls is mediated here, which is where [access rules](/contents/tech/core-concepts/access-rules-and-auth-zones) are checked.

## Object Modules

Three [object modules](https://github.com/radixdlt/radixdlt-scrypto/tree/main/radix-engine-interface/src/object_modules) can be attached to any object, and they are defined at this layer rather than being blueprint code: [Metadata](/contents/tech/core-concepts/metadata-module), which carries the typed key-value data wallets and explorers read; Royalty, which attaches per-method fees payable to a component or package owner; and [Role Assignment](/contents/tech/core-concepts/role-assignment-module), which binds named roles to the [badges](/contents/tech/core-concepts/badges) that satisfy them. Attaching behaviour as modules rather than inheriting it is what lets every object – native or user-defined – carry the same metadata, royalty and authorisation semantics.

## Native Blueprints

The engine’s built-in blueprints are declared at the system layer in [`radix-engine-interface/src/blueprints`](https://github.com/radixdlt/radixdlt-scrypto/tree/main/radix-engine-interface/src/blueprints) and executed natively rather than as WebAssembly. They include the resource and [component](/contents/tech/core-concepts/components) primitives; Account and Identity; Package; [Pool](/contents/tech/core-concepts/radix-pools); [ConsensusManager](/contents/tech/core-concepts/consensus-manager); [AccessController](/contents/tech/core-concepts/access-controller); [Locker](/contents/tech/core-concepts/locker-blueprint); and the [TransactionProcessor](/contents/tech/core-concepts/transaction-processor) and [TransactionTracker](/contents/tech/core-concepts/transaction-tracker) that turn a submitted [manifest](/contents/tech/core-protocols/transaction-manifests) into engine calls and record what has already been seen. Because they are ordinary blueprints from the caller’s point of view, [Scrypto](/contents/tech/core-protocols/scrypto-programming-language) code composes with them exactly as it composes with user-authored ones.

## System Versions

The kernel below this layer carries a version of its own and changes far less often across [protocol updates](/contents/tech/releases/protocol-updates): `KernelBoot` has advanced once, from V1 to V2 at Cuttlefish, and that bump only widened the set of always-visible global nodes (see [Kernel Layer](/contents/tech/core-protocols/kernel-layer#kernel-versions)). The system layer changes with nearly every update, and it carries a version number saying which set of rules is in force. The engine reads that number from a `SystemBoot` substate held on the boot-loader partition of the [TransactionTracker](/contents/tech/core-concepts/transaction-tracker), before it executes anything ([`system_callback.rs`](https://github.com/radixdlt/radixdlt-scrypto/blob/v1.4.0/radix-engine/src/system/system_callback.rs)). Enacting a protocol update that changes system behaviour therefore means flashing a replacement `SystemBoot` onto that partition, carrying the previous parameters across and advancing the version – no blueprint is published and no ledger state is migrated. The substate itself only exists from Bottlenose onward: before that the loader has nothing to read and falls back to the Babylon genesis parameters.

The enum is declared in the source as system logic which may change given a protocol version, and each behaviour it gates is a comparison against it rather than a branch on the update’s name.

| Version | Reached mainnet with | What the version gates |
| --- | --- | --- |
| `V1` | [Babylon](/contents/tech/releases/radix-mainnet-babylon) genesis; unchanged by Anemone and Bottlenose | A transaction is run as a single `call_function` into the [TransactionProcessor](/contents/tech/core-concepts/transaction-processor) blueprint, the auth zone is built from that call, its proofs are injected into it, and client-side costing is skipped at the outermost frame. |
| `V2` | Cuttlefish, part 1 | Execution moves to the multi-threaded intent processor, which is what lets one transaction carry [subintents](/contents/tech/core-concepts/subintents-and-pre-authorizations); the transaction intent starts being charged for. |
| `V3` | Cuttlefish, part 2 | The `VERIFY_PARENT` manifest instruction stops resolving against the root actor, which is the V2-and-below behaviour. |
| `V4` | Never – Dugong was not enacted | One behaviour, and it is written as an equality rather than a floor: asserting an access rule becomes a no-op while the auth module is disabled. The source comments that Dugong’s V4-only behavior must not carry into later versions. |
| `V5` | [Eagle Ray](/contents/tech/releases/protocol-updates#eagle-ray-enacted), epoch 339,898, 11 September 2026 | The receiver check, below. |

**Mainnet has never run V4.** Cuttlefish left the network at V3 in December 2024, Dugong never reached an enactment configuration, and Eagle Ray writes V5 over whatever it finds. The one V4-only behaviour has accordingly never been in force on mainnet – which is what the source comment is guarding, since a predicate written as `>= V4` rather than `== V4` would have quietly switched it on in September 2026.

### The receiver check (V5)

V5 enables a single test on the invocation path, and it belongs to this layer precisely because this is where a call is mediated. Before an invocation proceeds, the system asks whether the calling frame can see the node whose method it is about to call. A `Direct` method – the kind used for recall and other direct [vault](/contents/tech/core-concepts/buckets-proofs-and-vaults) access – requires direct visibility of the receiver; ordinary `Main` and module methods require ordinary visibility; roots, functions and blueprint hooks are exempt. A call that fails is rejected with `SystemError::InvalidInvokeAccess`, an error no version before V5 can return. The [asset drain and network halt of August 2026](/contents/history/hyperlane-asset-drain-2026) is what the check was written in response to.

## External Links

- [radix-engine-interface](https://github.com/radixdlt/radixdlt-scrypto/tree/main/radix-engine-interface)
- [Radix Engine docs](https://docs.radixdlt.com/docs/engine-tech-docs)
- [`system_callback.rs` at Scrypto v1.4.0](https://github.com/radixdlt/radixdlt-scrypto/blob/v1.4.0/radix-engine/src/system/system_callback.rs) – `SystemBoot`, `SystemVersion` and the behaviours each version gates
- [`eagle_ray.rs`](https://github.com/radixdlt/radixdlt-scrypto/blob/v1.4.0/radix-engine/src/updates/eagle_ray.rs) – the 80-line update that flashes `SystemBoot` to V5
