01 Introduction to Scrypto 101
1.2 Primer on Scrypto
This section will provide a top-level overview to Scrypto concepts. Many of the concepts explored here attempt to provide a holistic understanding of Scrypto. As such, we’ll be as general as possible to give you enough context to have a working understanding and as we go through the course, we’ll fill in the gaps that may exist in this section. It may also be useful to refer back to this page every chapter to put what you just learned back into perspective from a birds eye view.
//Introduction
Scrypto is based on Rust – and keeps most of Rust’s features – but adds a range of specific asset-oriented features to program smart contracts with the Radix Engine. It isn’t just Rust running on a public DLT network; it’s an asset-oriented language that allows Rust-style logic to interact not only with data (as with typical programming, and most smart contracts) but with assets (known as resources in Scrypto) as native, first-class citizens. We’ll get into this more, but the essence of what this means is that resources do not need to be programmatically defined within a smart contract. Resources are already clearly defined by the Radix Engine with physical properties that make their handling intuitive and straightforward.
For developers, the benefit of this is that you no longer have to constantly re-define what a token is through a deployment of smart contracts. The Radix Engine already has this primitive, which is exposed through Scrypto and allows you to easily create tokens on the fly with powerful properties that you care about which can synergize with your dApp. Because resources are clearly defined by the Radix Engine, developers can manage and manipulate resources frictionlessly, predictably, and reliably between dApps built on the Radix Network.
This universal understanding of resources by the Radix Engine means developers can spend more time building features for their dApp.
Instead of jumping straight into what Scrypto code looks like, this section provides an overview of Scrypto’s asset-oriented features, and the lifecycle of a component (a Scrypto smart contract). You’ll see how Scrypto naturally allows the developer to focus on their own business logic and lean on Radix Engine for intuitive, safe handling of assets. The result is that building DeFi in Scrypto finally provides the ease, safety, reusability, and composability that DeFi needs to fulfill its world-changing potential.
For developers, the benefit of this is that you no longer have to constantly re-define what a token is through a deployment of smart contracts. The Radix Engine already has this primitive, which is exposed through Scrypto and allows you to easily create tokens on the fly with powerful properties that you care about which can synergize with your dApp. Because resources are clearly defined by the Radix Engine, developers can manage and manipulate resources frictionlessly, predictably, and reliably between dApps built on the Radix Network.
This universal understanding of resources by the Radix Engine means developers can spend more time building features for their dApp.
Instead of jumping straight into what Scrypto code looks like, this section provides an overview of Scrypto’s asset-oriented features, and the lifecycle of a component (a Scrypto smart contract). You’ll see how Scrypto naturally allows the developer to focus on their own business logic and lean on Radix Engine for intuitive, safe handling of assets. The result is that building DeFi in Scrypto finally provides the ease, safety, reusability, and composability that DeFi needs to fulfill its world-changing potential.
//Resources, Buckets, and Vaults
Let’s start with the assets themselves, such as a token that you might want to create. In Scrypto, tokens aren’t smart contracts at all. Instead, they are a specific type of resource native to the platform with a finite set of behaviors designed to model physical assets behaviors in the real world. To create a new resource, like a token, you use a built-in Scrypto function where you can specify the parameters you want.
Let’s say you want to create a fixed supply of 1,000,000 tokens called MyCoin. You pass this supply and name (and other parameters) to the resource builder function as part of the resource definition and it returns you 1,000,000 new MyCoins.
One of the FSM(finite state machine) rules the Radix Engine requires is that resources must always be “physically” located somewhere, thus the MyCoins returned from the resource builder function must immediately be put in a container. These containers can either be temporary (a bucket) or permanent ( a vault). Temporary containers like buckets can be moved within components and outside of components; whereas vaults, while permanent, can’t be moved and can only live within a component. Resources with a supply are automatically put in a temporary container called a bucket. A bucket isn’t a variable that holds a number; it behaves like an actual container that resources can be put into or taken from. Because these are temporary containers, buckets must be disposed of by the end of transaction execution. Since resources must always be physically located in a container, buckets containing resources must be deposited into a vault that is always located within a component. This mechanism enables intuitive resource management between components, ensuring that buckets are securely stored within a component's vault.
So we can picture creation of a resource like this, with newly-created tokens going into a bucket that is then immediately placed into a vault for storage until a later transaction:
Let’s say you want to create a fixed supply of 1,000,000 tokens called MyCoin. You pass this supply and name (and other parameters) to the resource builder function as part of the resource definition and it returns you 1,000,000 new MyCoins.
One of the FSM(finite state machine) rules the Radix Engine requires is that resources must always be “physically” located somewhere, thus the MyCoins returned from the resource builder function must immediately be put in a container. These containers can either be temporary (a bucket) or permanent ( a vault). Temporary containers like buckets can be moved within components and outside of components; whereas vaults, while permanent, can’t be moved and can only live within a component. Resources with a supply are automatically put in a temporary container called a bucket. A bucket isn’t a variable that holds a number; it behaves like an actual container that resources can be put into or taken from. Because these are temporary containers, buckets must be disposed of by the end of transaction execution. Since resources must always be physically located in a container, buckets containing resources must be deposited into a vault that is always located within a component. This mechanism enables intuitive resource management between components, ensuring that buckets are securely stored within a component's vault.
So we can picture creation of a resource like this, with newly-created tokens going into a bucket that is then immediately placed into a vault for storage until a later transaction:

This can be done in just a couple of lines of Scrypto code.Scrypto provides functions that allow you to do things like take a quantity of resources from a bucket or vault, and put them into other buckets or vaults. We’ll see later how this makes interacting with resources much more direct and safe than the typical smart contract method.
//Components and Methods
We have resources, but what about smart contract logic?
The Radix Engine version of a smart contract is something we call a “component”. Because components are designed around resources, they don’t just hold data (like ints or strings); they also hold vaults that contain all resources owned by the component. In fact, every vault is owned by a component (and a component may own multiple vaults).
So the component’s code defines the kind of data it holds and the kinds of vaults it holds (each vault only accepts a specific type of resource). It also defines a list of methods that contain all of the logic of the component and creates the component’s interface to the world.
Putting it all together, we can picture an example component like this, ready to be used via its method1 and method2:
The Radix Engine version of a smart contract is something we call a “component”. Because components are designed around resources, they don’t just hold data (like ints or strings); they also hold vaults that contain all resources owned by the component. In fact, every vault is owned by a component (and a component may own multiple vaults).
So the component’s code defines the kind of data it holds and the kinds of vaults it holds (each vault only accepts a specific type of resource). It also defines a list of methods that contain all of the logic of the component and creates the component’s interface to the world.
Putting it all together, we can picture an example component like this, ready to be used via its method1 and method2:

//Blueprints and Packages
But wait, what is that “BlueprintA” we see next to the component’s title? That is the name of the blueprint the component was instantiated from. Unlike on typical smart contract platforms, active components aren’t simply deployed directly to the Radix network. All components start their life as a blueprint that is deployed to the Radix network and that acts like a template from which many component instances may be instantiated (each perhaps customized with input parameters).
This means that the Scrypto code (including its definition of the methods and types of data and vaults) is actually in the blueprint; the component’s logic and structure is fully defined there. But the component’s actual state - its data and resources - belong exclusively to that individual component, not the blueprint.
Once a component has been instantiated from a blueprint, it becomes active for use on the network by users (via method calls from transactions) or other components (via method calls from Scrypto code). Instantiation of a component from a blueprint happens using a function on the blueprint that performs the instantiation, like this:
This means that the Scrypto code (including its definition of the methods and types of data and vaults) is actually in the blueprint; the component’s logic and structure is fully defined there. But the component’s actual state - its data and resources - belong exclusively to that individual component, not the blueprint.
Once a component has been instantiated from a blueprint, it becomes active for use on the network by users (via method calls from transactions) or other components (via method calls from Scrypto code). Instantiation of a component from a blueprint happens using a function on the blueprint that performs the instantiation, like this:

(Note: You might notice one last little detail – the “PackageA” enclosing the blueprint. Multiple blueprints may be grouped together by the developer in a package.)Blueprints encourage reusability of Scrypto code, and also give the developer great flexibility to perform a variety of setup and configuration actions. In fact, an instantiator function offered by a blueprint may do much more than just instantiate a single component. It may instantiate multiple different components, as well as create new resources. Here’s an example (with the blueprint and component details simplified) of one blueprint instantiating two components and creating two new resources:

In addition to blueprints created by developers, Radix intends to deploy its own set of useful blueprints for anyone to use and instantiate on-ledger.
//Using Components with Resources
Now that we can instantiate components, how do we interact with them programmatically? Similar to typical smart contracts, we use the methods offered by the component. But Scrypto methods have a significant difference: they can directly accept (buckets of) resources.
Passing resources to a component method isn’t just sending a number or a reference to some tokens. Radix Engine treats it as actually transferring the ownership of those tokens to the component. Once the component has received a bucket of resources (or multiple buckets), it can take resources out of that bucket and put them elsewhere like a vault it holds, or a different bucket. The Radix Engine guarantees that the caller can no longer access that bucket – it has transferred it away.
The result is a much simpler and safer way of using tokens and other kinds of assets with component-based dApps on Radix. Take the example of a gumball machine component that accepts some USD tokens in exchange for a Gumball token (with a supply held in the gumball machine’s vault):
Passing resources to a component method isn’t just sending a number or a reference to some tokens. Radix Engine treats it as actually transferring the ownership of those tokens to the component. Once the component has received a bucket of resources (or multiple buckets), it can take resources out of that bucket and put them elsewhere like a vault it holds, or a different bucket. The Radix Engine guarantees that the caller can no longer access that bucket – it has transferred it away.
The result is a much simpler and safer way of using tokens and other kinds of assets with component-based dApps on Radix. Take the example of a gumball machine component that accepts some USD tokens in exchange for a Gumball token (with a supply held in the gumball machine’s vault):

A bucket of 0.25 USD is passed to the insertCoins method of the myMachine component (previously instantiated from a GumballMachine blueprint), and the machine’s logic sees that the correct price has been paid, puts those tokens in its USD vault, takes 1 Gumball from its Gumball vault, and passes it back to the caller. The component’s logic might also send back change if the user passed in too much USD.
Just how we’d expect a gumball machine to work!
On Ethereum, this would have involved the user calling a USD smart contract to give permission for the machine to withdraw on their behalf and telling the machine that they wish to input 0.25 USD, with the machine then calling the USD contract to do the withdraw, calling a Gumball contract to do the send to the user, and probably updating an internal cache of the number of Gumballs remaining for error checking. Every one of those extra smart contracts, and all of those smart contract calls, are opportunities for error – and this is just a simple gumball machine!
Just how we’d expect a gumball machine to work!
On Ethereum, this would have involved the user calling a USD smart contract to give permission for the machine to withdraw on their behalf and telling the machine that they wish to input 0.25 USD, with the machine then calling the USD contract to do the withdraw, calling a Gumball contract to do the send to the user, and probably updating an internal cache of the number of Gumballs remaining for error checking. Every one of those extra smart contracts, and all of those smart contract calls, are opportunities for error – and this is just a simple gumball machine!
//Transactions and Accounts
While you can imagine how one component might interact with another like this, at some point there must be a user transaction that kicks all of this off. How do transactions in the asset-oriented model work? What about accounts?
In short, transactions with the Radix Engine are also asset-oriented. They describe how the user wants resources that they control to flow to other components. They can even describe how to handle resources that are returned from a component – whether claimed by the user or passed on to another component in a composed multi-component transaction. (This also is a tremendous difference from Ethereum where a transaction is typically just a message to a smart contract that the user hopes will produce the desired result – and where composition of multiple smart contracts is not possible on the fly in transactions.)
To make sense of this type of transaction, we need to understand how accounts work. An account in the Radix Engine is a special kind of component that holds vaults just like any other component but also has some additional built-in functionality. Each account component is instantiated from a common Native Account blueprint on the Radix network that provides useful methods and consistent account behaviors. So Alice’s account might look (in simplified form) something like this:
In short, transactions with the Radix Engine are also asset-oriented. They describe how the user wants resources that they control to flow to other components. They can even describe how to handle resources that are returned from a component – whether claimed by the user or passed on to another component in a composed multi-component transaction. (This also is a tremendous difference from Ethereum where a transaction is typically just a message to a smart contract that the user hopes will produce the desired result – and where composition of multiple smart contracts is not possible on the fly in transactions.)
To make sense of this type of transaction, we need to understand how accounts work. An account in the Radix Engine is a special kind of component that holds vaults just like any other component but also has some additional built-in functionality. Each account component is instantiated from a common Native Account blueprint on the Radix network that provides useful methods and consistent account behaviors. So Alice’s account might look (in simplified form) something like this:

Let’s say you’re Alice and you want to send Bob 5 Cerb tokens. Your transaction would specify that you want to withdraw 5 Cerb from your Cerb vault (which you have permission to do via your signature) and then pass all of those tokens to the deposit method of Bob’s account component. As we discussed earlier, resources must always be located somewhere, so a bucket is used to pass them to Bob in the transaction. So the transaction contents would look something like this:

(Note: That’s not the actual syntax of transactions, but it gives you the right idea.)
Notice again that when we pass the 5 Cerb to Bob, we are actually passing a bucket containing those resources to the deposit method, not a reference or a call to a token smart contract elsewhere.
Interacting with any other component, such as our gumball machine above or a DeFi dApp component works in just the same way. You typically withdraw some tokens from your account, and pass them to the relevant method of the component you wish to call (perhaps along with some data that it may also require as input arguments).
Notice again that when we pass the 5 Cerb to Bob, we are actually passing a bucket containing those resources to the deposit method, not a reference or a call to a token smart contract elsewhere.
Interacting with any other component, such as our gumball machine above or a DeFi dApp component works in just the same way. You typically withdraw some tokens from your account, and pass them to the relevant method of the component you wish to call (perhaps along with some data that it may also require as input arguments).
//Authentication with Badges
Safely managing tokens and other assets is one of the recurring challenges with Ethereum and other typical smart contract platforms, but another is that of authorization. Virtually, every smart contract has some methods that it wishes to protect. For example, authorization might be used on special methods reserved for the contract’s owner, the rights to mint and burn tokens, or to restrict access to a whitelist of members.
Today this is typically done by keeping track of a list of account addresses (or smart contract addresses) that are allowed to do certain things. Unfortunately handling authorization in this way is inflexible and frequently creates a new vector of attack if the right checks on the list aren’t performed correctly.
This problem is also solved elegantly by Radix Engine’s asset-oriented design. This is because resources like, tokens, can actually be used for auth. We call the pattern of using resources for auth, badges. Scrypto provides special functions that easily allow components (including account components) to present a proof of a badge to another component.
Presenting a badge isn’t the same as transferring it; it provides the presentee with a reference to that badge (which we call proofs) so that it can be certain that the presenter in fact owns it without having to send the badge - risking the chance of losing the badge to a malicious component! This makes badges excellent for use in even very complex authorization patterns. Rather than checking a whitelist of addresses, a set of custom badges can be created and issued to accounts (or other components) which a component can easily check for. If the right badge isn’t present in the relevant method call, it can be rejected right away.
We will discuss more of exactly how this works later in the course and why this is an incredibly exciting feature!
Today this is typically done by keeping track of a list of account addresses (or smart contract addresses) that are allowed to do certain things. Unfortunately handling authorization in this way is inflexible and frequently creates a new vector of attack if the right checks on the list aren’t performed correctly.
This problem is also solved elegantly by Radix Engine’s asset-oriented design. This is because resources like, tokens, can actually be used for auth. We call the pattern of using resources for auth, badges. Scrypto provides special functions that easily allow components (including account components) to present a proof of a badge to another component.
Presenting a badge isn’t the same as transferring it; it provides the presentee with a reference to that badge (which we call proofs) so that it can be certain that the presenter in fact owns it without having to send the badge - risking the chance of losing the badge to a malicious component! This makes badges excellent for use in even very complex authorization patterns. Rather than checking a whitelist of addresses, a set of custom badges can be created and issued to accounts (or other components) which a component can easily check for. If the right badge isn’t present in the relevant method call, it can be rejected right away.
We will discuss more of exactly how this works later in the course and why this is an incredibly exciting feature!
//Benefits of Scrypto
Now, understanding the new tools provided by Scrypto (and Radix Engine behind the scenes), you can see the benefits of an asset-oriented approach. If you wish to write something like Uniswap in Scrypto, you can focus on writing only the code that matters: your unique swapping logic. Interacting with tokens (as resources), pools (vaults), and users (just another component) is direct and simple.
In fact, let's return to the comparison between “Uniswap as we imagine it” and “Uniswap on Ethereum today” from the top of the previous article. What would a swap transaction with the Scrypto implementation look like? Something like this:
In fact, let's return to the comparison between “Uniswap as we imagine it” and “Uniswap on Ethereum today” from the top of the previous article. What would a swap transaction with the Scrypto implementation look like? Something like this:

Just as we imagined it to be! Using Scrypto, the only code that needs to be written is an implementation of the trade method that looks at the incoming bucket of Token A resources, calculates the current exchange rate (based directly on the contents of its own internally-held pool vaults), and returns the right amount of Token B. All of the token manipulation performed by the trade method implementation happens via simple take/put functions on buckets and vaults.
The transaction itself would look something like this:
The transaction itself would look something like this:

No need for the user to give blanket withdrawal permission to Uniswap here; just a direct specification of the desired movement of resources between components. Safe, flexible, and naturally composable.
This sort of simplicity and directness should fire the imagination of developers with great ideas for the next generation of DeFi, and finally make possible a tidal wave of the kind of rich, robust dApps that are needed to revolutionize and remake global finance for the better.
This sort of simplicity and directness should fire the imagination of developers with great ideas for the next generation of DeFi, and finally make possible a tidal wave of the kind of rich, robust dApps that are needed to revolutionize and remake global finance for the better.