RADIX WikiRADIX Wiki

Overview

In this tutorial you'll build a Gumball Machine — a simple component that sells gumball tokens for XRD. Along the way you'll learn the core Scrypto concepts: blueprints, components, resources, and vaults.

Create a Package

A package is the deployment unit in Scrypto — it contains one or more blueprints.

scrypto new-package gumball_machine
cd gumball_machine

This creates:

gumball_machine/
├── Cargo.toml      # Dependencies
├── src/
│   └── lib.rs      # Blueprint code
└── tests/
    └── lib.rs      # Tests

Write the Blueprint

Replace src/lib.rs with the following. Each section is explained below.

use scrypto::prelude::*;
 
#[derive(ScryptoSbor)]
pub struct Status {
    pub price: Decimal,
    pub amount: Decimal,
}
 
#[blueprint]
mod gumball_machine {
    struct GumballMachine {
        gum_resource_manager: ResourceManager,
        gumballs: Vault,
        collected_xrd: Vault,
        price: Decimal,
    }
 
    impl GumballMachine {
        pub fn instantiate(price: Decimal) -> Global<GumballMachine> {
            let gumballs = ResourceBuilder::new_fungible(OwnerRole::None)
                .metadata(metadata!(
                    init {
                        "name" => "Gumball", locked;
                        "symbol" => "GUM", locked;
                    }
                ))
                .mint_initial_supply(100)
                .into();
 
            Self {
                gum_resource_manager: gumballs.resource_manager(),
                gumballs: Vault::with_bucket(gumballs),
                collected_xrd: Vault::new(XRD),
                price,
            }
            .instantiate()
            .prepare_to_globalize(OwnerRole::None)
            .globalize()
        }
 
        pub fn buy_gumball(&mut self, mut payment: Bucket) -> (Bucket, Bucket) {
            let cost = self.price.clone();
            let our_share = payment.take(cost);
            self.collected_xrd.put(our_share);
            (self.gumballs.take(1), payment)
        }
 
        pub fn get_status(&self) -> Status {
            Status {
                price: self.price.clone(),
                amount: self.gumballs.amount(),
            }
        }
    }
}

Key Concepts

  • Blueprint — a template (like a class). The #[blueprint] macro exposes it to the Radix Engine.
  • Component — a live instance of a blueprint, created by instantiate().
  • Resource — a first-class digital asset. ResourceBuilder creates a new fungible token ("Gumball").
  • Vault — permanent on-ledger storage for resources. Components hold assets in vaults.
  • Bucket — a transient container for moving resources between vaults during a transaction.

Notice there is no balance tracking or transfer logic — the Radix Engine handles asset management natively.

Build

scrypto build

This compiles to WebAssembly at target/wasm32-unknown-unknown/release/gumball_machine.wasm.

Test with resim

resim is the Radix Engine Simulator — a local ledger you can use without connecting to any network.

# Reset the simulator
resim reset
 
# Create a test account (saves address to $account)
resim new-account
 
# Publish the package
resim publish .
# Note the package address in the output
 
# Instantiate a GumballMachine with price = 5 XRD
resim call-function <PACKAGE_ADDRESS> GumballMachine instantiate 5
# Note the component address in the output
 
# Buy a gumball by sending 10 XRD
resim call-method <COMPONENT_ADDRESS> buy_gumball "10,resource_sim1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxakj8n3"
 
# Check your account
resim show <ACCOUNT_ADDRESS>

You should see GUM tokens in your account and 5 XRD change returned.

Handy resim commands

resim show <address> — inspect any entity. resim new-token-fixed 1000 — create test tokens. resim reset — wipe and start fresh.

Next Steps