RADIX WikiRADIX Wiki

Resources

A resource is any digital asset on Radix – tokens, NFTs, badges, LP tokens, etc. Unlike Solidity where tokens are contract state, Radix resources are native engine primitives with built-in rules for minting, burning, transferring, and access control.

There are two kinds:

  • Fungible – identical, interchangeable units (e.g., XRD, stablecoins)
  • Non-fungible – unique items with individual data (e.g., NFTs, access badges)

Creating Fungible Resources

let my_token: Bucket = ResourceBuilder::new_fungible(OwnerRole::None)
    .metadata(metadata!(
        init {
            "name" => "My Token", locked;
            "symbol" => "MYT", locked;
        }
    ))
    .mint_initial_supply(1_000_000)
    .into();

This creates 1 million tokens with locked name and symbol. The : Bucket annotation is required from Scrypto v1.4.0: without it .into() has no target type, and the build stops with error E0282, type annotations needed, as soon as the variable is used. The OwnerRole::None means no one can change the resource's configuration after creation.

Creating Non-Fungible Resources (NFTs)

#[derive(ScryptoSbor, NonFungibleData)]
pub struct Ticket {
    pub event_name: String,
    pub seat: u32,
    #[mutable]
    pub used: bool,
}
 
let tickets: Bucket = ResourceBuilder::new_integer_non_fungible::(OwnerRole::None)
    .metadata(metadata!(
        init {
            "name" => "Event Ticket", locked;
        }
    ))
    .mint_initial_supply([
        (IntegerNonFungibleLocalId::new(1), Ticket {
            event_name: "RadFest".into(),
            seat: 42,
            used: false,
        }),
    ])
    .into();

Fields marked #[mutable] can be updated later via the ResourceManager. Immutable fields are fixed at mint time.

Vaults and Buckets

Resources must always be inside a container:

ContainerLifetimePurpose
VaultPermanent (on-ledger state)Store resources between transactions
BucketTransient (single transaction)Move resources during a transaction

The Radix Engine enforces that all buckets must be empty by the end of every transaction. This guarantees no resources are accidentally lost or left in limbo.

// Take 10 tokens from a vault into a bucket
let bucket: Bucket = self.my_vault.take(10);
 
// Put them into another vault
self.other_vault.put(bucket);

Typed variants (FungibleVault, NonFungibleVault, FungibleBucket, NonFungibleBucket) provide type-safe operations when you know the resource type at compile time.

Proofs

Proofs let you demonstrate ownership of a resource without transferring it – like showing an ID badge without handing it over.

// Create a proof of one admin badge held in a vault
let proof = self.admin_badge.as_fungible().create_proof_of_amount(1);
 
// A proof made in a blueprint comes back to you. Push it onto the
// Auth Zone, where the Radix Engine checks it against access rules
LocalAuthZone::push(proof);

A Vault has no create_proof_of_all: fungible vaults prove an amount and non-fungible vaults prove specific IDs, and LocalAuthZone is where a proof goes to count towards a call. authorize_with_amount(1, || ...) does both in one step and drops the proof when the closure returns.

Proofs are central to Radix's authorization model. Protected methods check for proofs in the caller's Auth Zone rather than checking msg.sender.

ResourceManager

Every resource has a ResourceManager – the on-ledger controller for that resource type. Use it to mint, burn, query supply, and update NFT data:

// Mint more tokens (if resource was created with mint role)
let new_tokens: Bucket = self.resource_manager.mint(500);
 
// Get total supply
let supply: Decimal = self.resource_manager.total_supply().unwrap();
 
// Update mutable NFT data
self.resource_manager.update_non_fungible_data(
    &nft_id,
    "used",
    true,
);

Next Steps

HydrateLast updated Sep 26, 2026v1.4.010 revisionsVerified Sep 26, 2026