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 = This creates 1 million tokens with locked name and symbol. 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 = 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:
| Container | Lifetime | Purpose |
|---|---|---|
| Vault | Permanent (on-ledger state) | Store resources between transactions |
| Bucket | Transient (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 from a vault
let proof = self.admin_badge.create_proof_of_all();
// The proof is automatically placed in the Auth Zone
// where the 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,
);