There are two kinds of state that a component can contain: data and resources.
Data is what you are already familiar with when dealing with typical programming concepts like variables and values. Data can be freely created, destroyed, copied, and passed around – just like normal.
Resources are special, and are a crucial part of how Scrypto makes financial applications and transactions safer and more predictable. Unlike data, once resources are created they can only be moved from owner to owner, never copied or unintentionally destroyed or lost.
Resources must always be stored in special containers – either a
Vault or a
Bucket – and Radix Engine enforces that no resource can ever be lost. In short, Radix Engine ensures that resources behave like "physical things" which is why they are used on Radix for all types of assets. Even the utility token of the Radix network, XRD, is a resource.
All resources have a resource manager that defines how all of the individual resources of that type behave. For example, the token name, symbol, and supply is defined in its resource manager. The individual tokens of that resource would then be stored in Vaults or Buckets. Each resource manager has its own unique address.
The first decision to make when creating a resource is if that type of resource will be fungible or non-fungible.
A quantity of fungible resources can be freely split into smaller quantities (up to a defined limit of divisibility), and smaller quantities can be recombined. Typical tokens (including the XRD token), where no two tokens have an individual identity, are created as fungible resources. Example uses of fungible resources include:
Utility or governance tokens
Liquidity provider tokens
Tokenized representations of commodities
With non-fungible resources, each individual resource unit is uniquely addressable and not divisible. You can think of a non-fungible resource manager as a grouped set of individual objects that have the same behavior, but where each unit is a standalone object with its own identity (and potentially its own unique associated data).
Even though non-fungible resources can be addressed individually, Scrypto also allows them to be addressed in a fungible way in situations where you don’t care about the individual identities of the resources.
Example uses of non-fungible resources include:
Tickets to an event with seat numbers
Representations of unique numbered documents or products
Deeds of ownership of property or other real assets
Transactable unique debt positions or derivatives
Throughout Scrypto documentation, you will often see references to badge resources. Badges are not their own low-level type of resource, but are a usage pattern where a resource is used to confer special permissions to the bearer. Badges may be modeled as either fungible or non-fungible resources, depending on the intended use.
Resources have configurable behavior which is intrinsically understood by the Radix engine and clearly communicated to consumers, such as wallets.
A developer is able to specify rules around things like who is able to mint more supply (if anyone), whether it requires special rights to deposit or withdraw it, and so forth. It is also possible to specify which of these rules can be changed after creation, and who is able to change those rules.
Please see the Access Control - Resources documentation for an explanation of how to define these rules, and examples of their usage.
In the default case, a resource behaves like a pile of rocks. That is, it is freely transferrable from any party to any other party, no more rocks can be created, and none may be destroyed.
Let’s make some rocks.
let rocks = ResourceBuilder::new_fungible() .metadata("name", "Some rocks") .initial_supply(100);
There you go, you’re now holding a
Bucket with 100 shiny new tokens.
Resources are temporarily stored in a
Bucket and eventually stored in a
Vault by the end of execution. Each
Vault only holds resources of the same type (ie. the same resource definition).
You can split or combine quantities of resources, respectively, using the
put() methods on the resource container.
You may also query the quantity of resources within a
Vault by calling the
It is important to note that buckets do not define a "send" method. If you want to send a token to a component, that component needs to define a method which accepts a
Bucket as input.