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_machineThis creates:
gumball_machine/
āāā Cargo.toml # Dependencies
āāā src/
ā āāā lib.rs # Blueprint code
āāā tests/
āāā lib.rs # TestsWrite 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.
ResourceBuildercreates 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 buildThis 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
- Deploy to Stokenet ā publish your package on the public testnet
- Scrypto Fundamentals ā deeper dive into the asset-oriented model
- Testing Scrypto Blueprints ā write proper unit and integration tests
