Run Your First Project

All done with installing the Scrypto toolchain? Great, let’s walk through the steps of running and interacting with some Scrypto code in your simulator environment, starting with a new project.

The basic process involves creating a blueprint package with some blueprint Scrypto code, deploying it to your local simulator (as if deploying it to the Radix network’s blueprint catalog), instantiating a Component from the blueprint, and interacting with the component via a simulated transaction.

Creating a New Blueprint Package

First, we’ll create a new blueprint package.

scrypto new-package tutorial

This will scaffold a simple package which contains a single Hello blueprint. Open the new package directory in an IDE with Rust support. Find the instructions on how to setup the VSCode IDE here.

Open up src/ to see the source that we’ll be compiling and deploying to the simulator.

code tutorial/src/

Hello provides a function which instantiates a new component with a new supply of tokens, and a method which allows the caller to get one of those tokens from the instantiated component.

Creating an Account

Before we can deploy, we first need to create an account on the simulator. resim provides commands to make it convenient to create and use accounts in the simulator environment.

Most of commands offered by the resim tool act within the context of an account.

resim new-account

You should get a success message, and at the bottom of the output you should see the created account component address, public/private key, and the NonFungibleGlobalId of your owner badge:

A new account has been created!
Account component address: account_sim1qwqkszh49ekz3fkr23pgxwhzs56vfkpluwljqm0f2s2qz4dzkw
Public key: 0234be4516e4b3ffef6374b7729085fb53aa6a3ff9026a7ed2d1008dd7bf27a77d
Private key: 703923f5c97746410e21039209b74bdd93b1f527bd39f89b70cad55002c68515
Owner badge: resource_sim1qpejs3j866d5slwq4zgp52u697qcl2ure59ct8wk2mcq9h0zyc:#1#
No configuration found on system. will use the above account as default.

Please do not use these credentials on the main network, as your private key will be stored in plain text.

If you do not see the line about setting your default account, then you already created an account previously. Either reset your entire simulator with the resim reset command and try again, or set this new account as your default account with the following command:


Save the address of your new account component to an environment variable to make your life easier later. For example:

export account=account_sim1qwqkszh49ekz3fkr23pgxwhzs56vfkpluwljqm0f2s2qz4dzkw
export pubkey=0234be4516e4b3ffef6374b7729085fb53aa6a3ff9026a7ed2d1008dd7bf27a77d
export privkey=703923f5c97746410e21039209b74bdd93b1f527bd39f89b70cad55002c68515

On Windows, do

# Using the PowerShell

Displaying the Account

You can look at the resources on your new account by running:

resim show $account

You will get something like this:

Component: account_sim1qwqkszh49ekz3fkr23pgxwhzs56vfkpluwljqm0f2s2qz4dzkw
Blueprint: { package_address: package_sim1qy4hrp8a9apxldp5cazvxgwdj80cxad4u8cpkaqqnhlsa3lfpe, blueprint_name: "Account" }
Access Rules
├─ Native(Method(Component(ClaimRoyalty))) => Group("royalty")
└─ Native(Method(Component(SetRoyaltyConfig))) => Group("royalty")
Default: AllowAll
├─ ScryptoMethod("deposit") => AccessRule(AllowAll)
├─ ScryptoMethod("balance") => AccessRule(AllowAll)
└─ ScryptoMethod("deposit_batch") => AccessRule(AllowAll)
Default: Protected(ProofRule(Require(StaticNonFungible(NormalResource[00b91737ee8a4de59d49dad40de5560e5754466ac84cf5432ea95d]:33023ba3f79b03df97b0f27d7139aa576cd50f6c95d18a58b207))))
State: Tuple(KeyValueStore("5c9a6210fae94cfcac80c095958bb162fc94f5207d13aa8ec3215c30f346ddc303040000"))
Key Value Store: AccountComponent[0381680af52e6c28a6c35442833ae28534c4d83fe3bf206de95414]
└─ ResourceAddress("resource_sim1qzkcyv5dwq3r6kawy6pxpvcythx8rh8ntum6ws62p95sqjjpwr") => Vault("5c9a6210fae94cfcac80c095958bb162fc94f5207d13aa8ec3215c30f346ddc305040000")
└─ { amount: 1000, resource address: resource_sim1qzkcyv5dwq3r6kawy6pxpvcythx8rh8ntum6ws62p95sqjjpwr, name: "Radix", symbol: "XRD" }

This reads as:

Caption Description


All RadixDLT accounts are component and as such they have a ComponentAddress.


A set of component belong to a blueprint. A set of Blueprints belong to a package. Packages have addresses, just like component.


All components have a set of authorization rules. Here everyone has access to the balance, try_deposit_or_abort and the try_deposit_batch_or_abort methods on the users account. This means that everyone can try to send you any token - which you will receive, assuming you haven’t set your account to deny deposits of certain resources.


Components have a data structure that contain all the data they can work on. This complete set of data stored by the component is called the state. The state of the account component consists in a single KeyValueStore where keys are ResourceAddresses (token addresses), and values are the Vaults that can store those resources on the account’s behalf.

Key Value Store

This section lists the key-value store (similar to a hashmap) associated with this component.


Here is the list of all the resources (tokens) the account owns. There are Fungible and Non-Fungible resources on the Radix DLT.

Deploying the Package

To publish our package we run this command:

cd tutorial
resim publish .

You should see the published package’s address in the output. Save that address in the $package environment variable.

export package=<package_address_returned_by_resim_publish>

Component Instantiation

Now that our package is deployed "on ledger" in the simulator, we will want to instantiate a component from its blueprint. Let’s investigate the Hello blueprint to see how we can do that.

// This is a function, and can be called directly on the blueprint once deployed
pub fn instantiate_hello() -> Global<Hello> {
    // Create a new token called "HelloToken," with a fixed supply of 1000, and put that supply into a bucket
    let my_bucket: Bucket = ResourceBuilder::new_fungible()
        .metadata("name", "HelloToken")
        .metadata("symbol", "HT")

    // Instantiate a Hello component, populating its vault with our supply of 1000 HelloToken
    Self {
        sample_vault: Vault::with_bucket(my_bucket)

instantiate_hello() is a function that creates a new component from this blueprint and returns its address. In detail:

  1. It creates a new Bucket with a Fungible Token of an initial supply of 1000.

  2. It creates a new Vault and puts the bucket into it.

  3. It calls the instantiate method on the component that will create the component without an Address,

  4. It calls the globalize method on the component to make it globally accessible adding an Address to it.

Now we will instantiate a Hello component by calling the instantiate_hello function on the Hello blueprint.

resim call-function $package Hello instantiate_hello

The output should look something like this:

Transaction Status: COMMITTED SUCCESS
Transaction Fee: 0.03471762 XRD used for execution, 0 XRD used for royalty, 0 XRD in bad debt
Cost Units: 100000000 limit, 330644 consumed, 0.0000001 XRD per cost unit, 5% tip
Logs: 0
├─ CALL_METHOD Address("component_sim1qftacppvmr9ezmekxqpq58en0nk954x0a7jv2zz0hc7q8utaxr") "lock_fee" Decimal("100");
├─ CALL_FUNCTION Address("package_sim1q8rgkswzqu683k3zj0e8zy9cn9a42td4efltj6r79acqrsv78g") "Hello" "instantiate_hello";
└─ CALL_METHOD Address("account_sim1qwqkszh49ekz3fkr23pgxwhzs56vfkpluwljqm0f2s2qz4dzkw") "try_deposit_batch_or_abort" Expression("ENTIRE_WORKTOP");
Instruction Outputs:
├─ ()
├─ Address("component_sim1qfqaeurzjaj3xxxhrxsc5vmsd8dkqpm9xdmvn689yvus6mwre8")
└─ ()
New Entities: 2
└─ Component: component_sim1qfqaeurzjaj3xxxhrxsc5vmsd8dkqpm9xdmvn689yvus6mwre8
└─ Resource: resource_sim1qrltuc5rnxuc4747f9fa0wgxp06hvyt90qv3egsyr7tq2p73nn

This reads as:



Transaction Status

Transaction was successful.

Transaction Fee and Cost Units

This sections describes the fees you had to pay to execute this transaction. Read more about fees here.


There were no logs.


The transaction first executed a call to lock the fees. Then it executed one CallFunction instruction, that called instantiate_hello function which in turn issued a CallMethod instruction.

Instruction Outputs

The CallFunction instruction returned the ComponentAddress of the new component and the CallMethod and fee locking instructions returned empty tuples.

New Entities

There were two new entities created: the Hello component and the HelloToken resource.

This will create two new entities with two different addresses:
  • a new HelloToken with a ResourceAddress,

  • and your fresh Hello component having a ComponentAddress

Save this to the $component environment variable:

export component=<component_address_returned_by_resim_call_function>

On Radix, tokens and other assets are created as system-level resources, not blueprints, and the definition of the resources contains the parameters for the supply you have requested from the system.

You can investigate these new addresses, if you wish:

resim show <address>

Component Call

First let’s investigate the free_token method:

// This is a method, because it needs a reference to self.  Methods can only be called on components
pub fn free_token(&mut self) -> Bucket {
    info!("My balance is: {} HelloToken. Now giving away a token!", self.sample_vault.amount());
    // If the semi-colon is omitted on the last line, the last value seen is automatically returned
    // In this case, a bucket containing 1 HelloToken is returned

The following is done in the free_token method:

  1. It logs an info message with the current balance of the HelloToken.

  2. It takes a Bucket with one of the HelloToken from the Vault and returns it to the caller.

  3. The Vault now has one less HelloToken in it.

All buckets must be returned to a Vault (or burned) by the end of the transaction, otherwise the system will return an error.

Next, we’ll call the free_token method on our new component.

resim call-method $component free_token

This requires a different resim command than the one we just used since we are now calling a method on an instantiated component instead of the function of a blueprint.

The output should look something like this:

Transaction Status: COMMITTED SUCCESS
Transaction Fee: 0.114503865 XRD used for execution, 0 XRD used for royalty, 0 XRD in bad debt
Cost Units: 100000000 limit, 1090513 consumed, 0.0000001 XRD per cost unit, 5% tip
Logs: 1
└─ [INFO ] My balance is: 1000 HelloToken. Now giving away a token!
├─ CALL_METHOD ComponentAddress("component_sim1qftacppvmr9ezmekxqpq58en0nk954x0a7jv2zz0hc7q8utaxr") "lock_fee" Decimal("100");
├─ CALL_METHOD ComponentAddress("component_sim1qfqaeurzjaj3xxxhrxsc5vmsd8dkqpm9xdmvn689yvus6mwre8") "free_token";
└─ CALL_METHOD ComponentAddress("account_sim1qwqkszh49ekz3fkr23pgxwhzs56vfkpluwljqm0f2s2qz4dzkw") "try_deposit_batch_or_abort" Expression("ENTIRE_WORKTOP");
Instruction Outputs:
├─ ()
├─ Bucket(1025u32)
└─ ()
New Entities: 0

This reads as:

Caption Description

Transaction status

Transaction was successful.

Transaction Fee and Cost Units

This sections describes the fees you had to pay to execute this transaction. Read more about fees here.


There was one log message. The message was: [INFO ] My balance is: 1000 HelloToken. Now giving away a token!


The transaction first locked the fees. Then it executed one CallMethod instruction, that called free_token method which in turn issued another CallMethod instruction to store the HelloToken in your account.

Instruction outputs

The first CallMethod instruction returned a Bucket containing one HelloToken. The second CallMethod and fee locking instruction returned empty tuples.

And now you have a shiny new HelloToken in your account, and your Hello component has one less. You can verify this with some investigation using resim show on each component.

You can create more accounts, and change which one you’re acting as, by running:

resim set-default-account <ACCOUNT_COMPONENT_ADDRESS> <PRIVATE_KEY>

Final Notes

If you make changes to the structs within your code, then unfortunately you will have to run through the entire publish-instantiate-call flow from scratch, saving the new addresses as they appear. If you only make implementation changes then it is possible to update your package with:

resim publish . --package-address $package

At any point you can instantly get a clean slate in the simulator by running:

resim reset

You almost certainly need to do this if you switch to working on a different project.

That concludes this most basic tutorial on using resim. We suggest to continue your learning journey by reading the "language description" section here.