RADIX WikiRADIX Wiki

Introduction

Radix enforces a strict invariant: every resource must exist inside a container at all times. There are two container types: Vaults (permanent, on-ledger storage) and Buckets (temporary, transaction-scoped carriers). The Radix Engine guarantees that resources cannot be duplicated, accidentally destroyed, or left in limbo – if your transaction ends with an undeposited bucket, it fails. This "physical resource" model eliminates entire categories of bugs common in other smart contract platforms.

Vault Patterns

Single-Vault Component

The simplest pattern: a component holds one vault to store a single resource type. A token sale component, for example, stores tokens in a vault and returns XRD payment to the buyer's account.

struct TokenSale {
    token_vault: Vault,    // holds tokens for sale
    xrd_vault: Vault,      // collects XRD payments
    price: Decimal,
}

Multi-Vault Component (HashMap)

When a component needs to manage arbitrary resource types (e.g. a DEX liquidity pool or a wallet-like component), use a HashMap<ResourceAddress, Vault>. When a new resource type is deposited, create a new vault; when an existing type arrives, deposit into the matching vault.

struct MultiVault {
    

Vault Take & Put

Withdraw resources from a vault with .take(amount) (returns a Bucket) or .take_all(). Deposit with .put(bucket). For non-fungibles, use .take_non_fungible(&id) or .take_non_fungibles(&ids) to withdraw specific items.

Bucket Patterns

Bucket Passing (Move Semantics)

Buckets use Rust's ownership model – passing a bucket to a function moves it. The caller no longer has access. This prevents double-spending at the language level:

// Caller creates a bucket, passes it to the component
let payment: Bucket = account.withdraw(xrd_address, dec!("100"));
let tokens: Bucket = sale_component.buy(payment);
// 'payment' is now consumed — cannot be used again
account.deposit(tokens);

Bucket Splitting

Use .take(amount) on a bucket to split it into two buckets – the original retains the remainder. This is how you implement partial fills, fee extraction, or distributing resources across multiple destinations within a single transaction.

The Worktop

In transaction manifests, returned resources land on the worktop – a temporary staging area. Use TAKE_FROM_WORKTOP to create named buckets from worktop resources, then pass them to subsequent method calls. The transaction fails if any resources remain on the worktop at the end.

Next Steps

HydrateLast updated Jul 27, 2026v1.4.19 revisionsVerified Jul 27, 2026