Skip to content

Commit

Permalink
Migrate examples from main repo
Browse files Browse the repository at this point in the history
  • Loading branch information
iamyulong committed Feb 18, 2022
1 parent 3277cf7 commit 5ea904c
Show file tree
Hide file tree
Showing 66 changed files with 5,758 additions and 1 deletion.
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Visual studio code
.vscode

# macOS folder attributes
.DS_Store

# Rust auto-generated
target/
Cargo.lock
**/*.rs.bk

# Flamegraph profiles
flamegraph.svg

# IntelliJ
.idea/

# Emacs
*~
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# scrypto-examples
# Scrypto Examples

This repository hosts all the official Scrypto examples.
4 changes: 4 additions & 0 deletions core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Scrypto Core Blueprints
Here you will find examples that either represent foundational learning for Scrypto, or teach a single concept in the most limited scope possible.

If you're unsure where to start, try [hello-world](hello-world), [hello-nft](hello-nft) or [gumball-machine](gumball-machine) for the basics.
20 changes: 20 additions & 0 deletions core/cross-blueprint-call/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "cross-blueprint-call"
version = "0.1.0"
edition = "2021"

[dependencies]
sbor = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.3.0" }
scrypto = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.3.0" }

[dev-dependencies]
radix-engine = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.3.0" }

[profile.release]
opt-level = 's' # Optimize for size.
lto = true # Enable Link Time Optimization.
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
panic = 'abort' # Abort on panic.

[lib]
crate-type = ["cdylib", "lib"]
85 changes: 85 additions & 0 deletions core/cross-blueprint-call/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Cross-Blueprint Call

When the complexity of a DeFi application increases, it's sometimes impossible to put all logic into one blueprint. Instead, we need a group of modular blueprints, each including a distinct subset of the business logic.

In this example, we demonstrate two ways of calling a function or method defined in a different blueprint, depending on where it's located.

## Callee Is From A Different Package

If the function or method is from an already published package, we need to
1. Export the ABI of the blueprint using tools like `resim`
```
resim export-abi <PACKAGE_ADDRESS> Airdrop
```
2. Import the ABI into our package, e.g.,
```rust
import! {
r#"
{
"package": "01bda8686d6c2fa45dce04fac71a09b54efbc8028c23aac74bc00e",
"name": "Airdrop",
"functions": [
{
"name": "instantiate_airdrop",
"inputs": [],
"output": {
"type": "Custom",
"name": "scrypto::core::Component",
"generics": []
}
}
],
"methods": [
{
"name": "free_token",
"mutability": "Immutable",
"inputs": [],
"output": {
"type": "Custom",
"name": "scrypto::resource::Bucket",
"generics": []
}
}
]
}
"#
}
```
Once the blueprint has been imported, we can then call any of its functions, for example,
```rust
let airdrop_component = Airdrop::instantiate_airdrop();
```

To call a method, though, we need a component address, which can be parsed from string.
```rust
let address = Address::from_str("022cf5de8153aaf56ee81c032fb06c7fde0a1dc2389040d651dfc2").unwrap();
let airdrop = Airdrop::from(address);
let received_tokens = airdrop.free_token();
```

## Callee Is From This Package

If the function or method you're calling is from this package, we can import the blueprint using Rust's `use` keyword.

In our example package, we have the following files:
```
├─ src
│ ├─ lib.rs
│ ├─ airdrop.rs
│ ├─ cross_package.rs
│ └─ intra_package.rs
├─ test
│ └─ lib.rs
└─ Cargo.toml
```

In `intra_package.rs`, we write

```rust
use crate::airdrop::Airdrop;
```

which is to import the `Airdrop` blueprint from the `airdrop` module under this crate.

Once imported, we can function/method the same way as when the callee is from a different package
29 changes: 29 additions & 0 deletions core/cross-blueprint-call/src/airdrop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use scrypto::prelude::*;

// This is a simple Airdrop blueprint. All components instantiated from it will initially
// hold 1000 FreeToken within a vault. When the `free_token` method is called, 1 FreeToken will be
// taken from the vault and returned to the caller.

blueprint! {
struct Airdrop {
tokens: Vault,
}

impl Airdrop {
pub fn instantiate_airdrop() -> Component {
Self {
tokens: Vault::with_bucket(
ResourceBuilder::new_fungible(DIVISIBILITY_MAXIMUM)
.metadata("name", "FreeToken")
.initial_supply_fungible(1000),
),
}
.instantiate()
}

pub fn free_token(&mut self) -> Bucket {
// Take 1 FreeToken and return
self.tokens.take(1)
}
}
}
54 changes: 54 additions & 0 deletions core/cross-blueprint-call/src/cross_package.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use scrypto::prelude::*;

import! {
r#"
{
"package": "01bda8686d6c2fa45dce04fac71a09b54efbc8028c23aac74bc00e",
"name": "Airdrop",
"functions": [
{
"name": "instantiate_airdrop",
"inputs": [],
"output": {
"type": "Custom",
"name": "scrypto::core::Component",
"generics": []
}
}
],
"methods": [
{
"name": "free_token",
"mutability": "Immutable",
"inputs": [],
"output": {
"type": "Custom",
"name": "scrypto::resource::Bucket",
"generics": []
}
}
]
}
"#
}

blueprint! {
struct Proxy1 {
airdrop: Airdrop,
}

impl Proxy1 {
pub fn instantiate_proxy() -> Component {
Self {
// The instantiate_airdrop() function returns a generic Component. We use `.into()` to convert it into an `Airdrop`.
airdrop: Airdrop::instantiate_airdrop().into(),
}
.instantiate()
}

pub fn free_token(&self) -> Bucket {
// Calling a method on a component using `.method_name()`.
self.airdrop.free_token()
}
}
}
24 changes: 24 additions & 0 deletions core/cross-blueprint-call/src/intra_package.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use scrypto::prelude::*;

use crate::airdrop::Airdrop;

blueprint! {
struct Proxy2 {
airdrop: Airdrop,
}

impl Proxy2 {
pub fn instantiate_proxy() -> Component {
Self {
// The instantiate_airdrop() function returns a generic Component. We use `.into()` to convert it into an `Airdrop`.
airdrop: Airdrop::instantiate_airdrop().into(),
}
.instantiate()
}

pub fn free_token(&self) -> Bucket {
// Calling a method on a component using `.method_name()`.
self.airdrop.free_token()
}
}
}
4 changes: 4 additions & 0 deletions core/cross-blueprint-call/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Here, we declared all the modules that should be included into this package.
mod airdrop;
mod cross_package;
mod intra_package;
79 changes: 79 additions & 0 deletions core/cross-blueprint-call/tests/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use radix_engine::ledger::*;
use radix_engine::transaction::*;
use scrypto::prelude::*;

#[test]
fn test_proxy_1() {
// Set up environment.
let mut ledger = InMemorySubstateStore::with_bootstrap();
let mut executor = TransactionExecutor::new(&mut ledger, false);
let key = executor.new_public_key();
let account = executor.new_account(key);
let package = executor
.publish_package(include_code!("cross_blueprint_call"))
.unwrap();

// Airdrop blueprint.
executor.overwrite_package(
Address::from_str("01bda8686d6c2fa45dce04fac71a09b54efbc8028c23aac74bc00e").unwrap(),
include_code!("cross_blueprint_call"),
);

// Test the `instantiate_proxy` function.
let transaction1 = TransactionBuilder::new(&executor)
.call_function(package, "Proxy1", "instantiate_proxy", vec![], None)
.build(vec![])
.unwrap();
let receipt1 = executor.run(transaction1).unwrap();
println!("{:?}\n", receipt1);
assert!(receipt1.result.is_ok());

// Test the `get_gumball` method.
let component = receipt1.component(0).unwrap();
let transaction2 = TransactionBuilder::new(&executor)
.call_method(component, "free_token", vec![], Some(account))
.call_method_with_all_resources(account, "deposit_batch")
.build(vec![key])
.unwrap();
let receipt2 = executor.run(transaction2).unwrap();
println!("{:?}\n", receipt2);
assert!(receipt2.result.is_ok());
}

#[test]
fn test_proxy_2() {
// Set up environment.
let mut ledger = InMemorySubstateStore::with_bootstrap();
let mut executor = TransactionExecutor::new(&mut ledger, false);
let key = executor.new_public_key();
let account = executor.new_account(key);
let package = executor
.publish_package(include_code!("cross_blueprint_call"))
.unwrap();

// Airdrop blueprint.
executor.overwrite_package(
Address::from_str("01bda8686d6c2fa45dce04fac71a09b54efbc8028c23aac74bc00e").unwrap(),
include_code!("cross_blueprint_call"),
);

// Test the `instantiate_proxy` function.
let transaction1 = TransactionBuilder::new(&executor)
.call_function(package, "Proxy2", "instantiate_proxy", vec![], None)
.build(vec![])
.unwrap();
let receipt1 = executor.run(transaction1).unwrap();
println!("{:?}\n", receipt1);
assert!(receipt1.result.is_ok());

// Test the `get_gumball` method.
let component = receipt1.component(0).unwrap();
let transaction2 = TransactionBuilder::new(&executor)
.call_method(component, "free_token", vec![], Some(account))
.call_method_with_all_resources(account, "deposit_batch")
.build(vec![key])
.unwrap();
let receipt2 = executor.run(transaction2).unwrap();
println!("{:?}\n", receipt2);
assert!(receipt2.result.is_ok());
}
20 changes: 20 additions & 0 deletions core/flat-admin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "flat-admin"
version = "0.1.0"
edition = "2021"

[dependencies]
sbor = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.3.0" }
scrypto = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.3.0" }

[dev-dependencies]
radix-engine = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.3.0" }

[profile.release]
opt-level = 's' # Optimize for size.
lto = true # Enable Link Time Optimization.
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
panic = 'abort' # Abort on panic.

[lib]
crate-type = ["cdylib", "lib"]
Loading

0 comments on commit 5ea904c

Please sign in to comment.