Skip to content

Update course content with some practice example #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 52 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
# Sui Object Model Workshop
# Sui Object Model and PTBs Workshop

When learning Sui Move, developers are encouraged to use best practices to utilize the Sui object model and ensure on-chain object composability. Developers learn to write composable move code in a timely manner, but struggle to verify their code by deploying and executing the functionality on chain. The key to mastering the Sui object model is to pair your Sui move development sessions with interacting with on-chain objects via PTBs (Programmable Transaction Blocks). This workshop will guide you through the process of writing Sui Move code, deploying it to the Sui blockchain, and interacting with on-chain objects via PTBs.

# Table of Contents
- [Sui Object Model Workshop](#sui-object-model-workshop)
- [Sui Object Model and PTBs Workshop](#sui-object-model-and-ptbs-workshop)
- [Table of Contents](#table-of-contents)
- [Environment Setup](#environment-setup)
- [Lessons](#lessons)
- [Handling Returned Objects](#handling-returned-objects)
- [Exercise](#exercise)
- [Objects as Input](#objects-as-input)
- [Exercise](#exercise-1)
- [Lesson 1: Handling Returned Objects](#lesson-1-handling-returned-objects)
- [Exercise 1: Handling Returned Sui NFT](#exercise-1-handling-returned-sui-nft)
- [Lesson 2: Objects as Input](#lesson-2-objects-as-input)
- [Exercise 2: Input Objects - Counter](#exercise-2-input-objects---counter)
- [Exercise 3: Scavenger Hunting with PTBs](#exercise-3-scavenger-hunting-with-ptbs)

# Environment Setup

Before we start, we need to set up our environment.
Before we start, we need to set up our environment for our scripts.

```bash
cd scripts && npm install
```

Navigate to the `scripts` directory and run the following command:

```bash
yarn init-keypair
npm run init-keypair
```

This will generate and fund a new keypair for you to use in the workshop. Make sure not to use this keypair in any production environments.

Sui Faucet: [https://faucet.sui.io/](https://faucet.sui.io/) OR [Discord faucet](https://discord.gg/cKx75xrRMq)

Sui Faucet options:
- [n1stake faucet](https://faucet.n1stake.com)
- [Official Sui faucet](https://faucet.sui.io/)
- [Discord faucet](https://discord.gg/cKx75xrRMq)

# Lessons

## Handling Returned Objects
## Lesson 1: Handling Returned Objects

One of the best practices when writing Sui Move packages is to avoid self-transfers. In other words, avoid transferring objects to the sender of the transaction, and instead return the object from the current function. This allows a caller or programmable transaction block to use the object however they see fit.

Expand Down Expand Up @@ -73,11 +80,22 @@ This is easy enough to do, but in most cases (when the object doesn't have the [

In this lesson, you learn how to handle returned objects properly.

### Exercise

View the contents [`banana.move`](./lessons/returning_objects/banana_without_display/sources/banana_without_display.move). There is a deployed instance of this package on the Sui blockchain. The address of the package is [`0xadfb946c8c887446d284dae80ac8501c02ec9b9157babb96ca884773bfbb7771`](https://suiscan.xyz/testnet/object/0xadfb946c8c887446d284dae80ac8501c02ec9b9157babb96ca884773bfbb7771/txs). Navigate to [`scripts/lessons/return_objects/exercise.ts`](./scripts/src/lessons/return_objects/exercise.ts) and complete the exercise.

## Objects as Input
### Exercise 1: Handling Returned Sui NFT


The package of the SUIII NFT is at [`0x83feeef5abcb1d5caca48f5e4e2259f8fbbcac88c10d82cc95ed58ff6f0dcd79`](https://suiscan.xyz/testnet/object/0x83feeef5abcb1d5caca48f5e4e2259f8fbbcac88c10d82cc95ed58ff6f0dcd79/tx-blocks) and the NFT object type is [`0x83feeef5abcb1d5caca48f5e4e2259f8fbbcac88c10d82cc95ed58ff6f0dcd79::sui_nft::SuiNFT`](https://suiscan.xyz/testnet/collection/0x83feeef5abcb1d5caca48f5e4e2259f8fbbcac88c10d82cc95ed58ff6f0dcd79::sui_nft::SuiNFT/items).


View the contract at [`sui_nft.move`](./lessons/returning_objects/sui_nft/sources/sui_nft.move). Try to mint an NFT to your account and view it at explorer with PTBs.

Navigate to [`scripts/src/return_objects_exercise.ts`](./scripts/src/return_objects_exercise.ts) and complete the exercise.

> Bonus Challenge: Can you deploy the [SUIII NFT package](./lessons/returning_objects/sui_nft) yourself and use different text and images for the NFT?
> [Install the Sui CLI](https://docs.sui.io/guides/developer/getting-started/sui-install), [Create Deployer Address](https://docs.sui.io/guides/developer/getting-started/get-address), and deposit gas coins from faucet, then use `sui client publish --skip-dependency-verification` to deploy!

## Lesson 2: Objects as Input

There are a lot of situations where one will want to interact with objects on Sui. Referencing and using objects in Sui Move is simple but nuanced. To reference an object in Sui Move, make the object a function parameter. For example,

Expand Down Expand Up @@ -107,6 +125,24 @@ The `delete` function receives the actual instance of the `SimpleObject` and del

This usage is straightforward, but tends to leave developers wondering what this looks out in a wider context. In this lesson, you learn how to use objects as inputs in PTBs.

### Exercise
### Exercise 2: Input Objects - Counter

View the contents [`counter.move`](./lessons/input_objects/counter/sources/counter.move). There is a deployed instance of this package on the Sui blockchain. The address of the package is [`0x8f0b6cbef998d26f03daa8a9e90d17d57bce8d4b45cb90911662a828f903d323`](https://suiscan.xyz/testnet/object/0x8f0b6cbef998d26f03daa8a9e90d17d57bce8d4b45cb90911662a828f903d323/txs) and the counter object is [0x33a950ff57b782bc66f6416bf3fdf7d44de94a84fa823b9b9291f49d4b0270da](https://suiscan.xyz/testnet/object/0x33a950ff57b782bc66f6416bf3fdf7d44de94a84fa823b9b9291f49d4b0270da/fields).


Navigate to [`scripts/src/input_objects_exercise.ts`](./scripts/src/input_objects_exercise.ts) and complete the exercise.


### Exercise 3: Scavenger Hunting with PTBs

In this exercise, you will try to get the `Bucket USD` coin in Testnet from the vault using a key created by PTBs. The deployed contract is at [`0x25dfcadb5927395b463a426e8d63425d654a6057affc368f4dc176e587f489a5`](https://suiscan.xyz/testnet/object/0x25dfcadb5927395b463a426e8d63425d654a6057affc368f4dc176e587f489a5/contracts).

Navigate to [`scavenger`](./lessons/scavenger) to read the smart contract code.

You will need to create a PTB to:
1. Create a key
2. Set the key code correctly
3. Use the key to withdraw the `Bucket USD` coin from the vault
4. Transfer the `Bucket USD` coin to your account

View the contents [`counter.move`](./lessons/input_objects/counter/sources/counter.move). There is a deployed instance of this package on the Sui blockchain. The address of the package is [`0xad3225e7d4827f81dc0686177067e1b458e8468ceabcff3456888ce3d806eb8c`](https://suiscan.xyz/testnet/object/0xad3225e7d4827f81dc0686177067e1b458e8468ceabcff3456888ce3d806eb8c/txs). Navigate to [`scripts/lessons/input_objects/exercise.ts`](./scripts/src/lessons/input_objects/exercise.ts) and complete the exercise.
Navigate to [`scripts/src/scavenger_hunt_exercise.ts`](./scripts/src/scavenger_hunt_exercise.ts) and complete the exercise.
16 changes: 8 additions & 8 deletions lessons/input_objects/counter/Move.lock
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
# @generated by Move, please check-in and do not edit manually.

[move]
version = 2
version = 3
manifest_digest = "10944AA0F1590CA15650646C66BA027B77D532E5295D19E52CD4671090E69164"
deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082"
dependencies = [
{ name = "Sui" },
{ id = "Sui", name = "Sui" },
]

[[move.package]]
name = "MoveStdlib"
id = "MoveStdlib"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/move-stdlib" }

[[move.package]]
name = "Sui"
id = "Sui"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/sui-framework" }

dependencies = [
{ name = "MoveStdlib" },
{ id = "MoveStdlib", name = "MoveStdlib" },
]

[move.toolchain-version]
compiler-version = "1.30.3"
compiler-version = "1.40.3"
edition = "2024.beta"
flavor = "sui"

[env]

[env.testnet]
chain-id = "4c78adac"
original-published-id = "0xad3225e7d4827f81dc0686177067e1b458e8468ceabcff3456888ce3d806eb8c"
latest-published-id = "0xad3225e7d4827f81dc0686177067e1b458e8468ceabcff3456888ce3d806eb8c"
original-published-id = "0x8f0b6cbef998d26f03daa8a9e90d17d57bce8d4b45cb90911662a828f903d323"
latest-published-id = "0x8f0b6cbef998d26f03daa8a9e90d17d57bce8d4b45cb90911662a828f903d323"
published-version = "1"
93 changes: 60 additions & 33 deletions lessons/input_objects/counter/sources/counter.move
Original file line number Diff line number Diff line change
@@ -1,41 +1,68 @@
module counter::counter {
module counter::counter;

/*
Struct for defining the Counter object type
use sui::balance;
use sui::coin;
use sui::sui::SUI;

Abilities:
- key: allows this type to be an object on Sui
/*
Struct for defining the Counter object type

Attributes:
- id: The object id of this object (required when using key ability)
- count: The current value of the counter
Abilities:
- key: allows this type to be an object on Sui

Further reading:
- key ability: https://move-book.com/storage/key-ability.html?highlight=key#the-key-ability
*/
public struct Counter has key {
id: UID,
Attributes:
- id: The object id of this object (required when using key ability)
- count: The current value of the counter
- collected_fees: Balance of SUI tokens collected as fees
- creator: Address of the creator of the counter
- min_fee: Minimum fee required to increment the counter

Further reading:
- key ability: https://docs.sui.ioonceptsbject-modelbject#object-capabilities
*/
public struct Counter has key {
id: UID,
count: u64,
}

/*
Init function that creates and shares a Counter object.

This function will be called once and only once during the package deployment.

Further reading:
- Shared objects: https://docs.sui.io/concepts/object-ownership/shared
*/
fun init(ctx: &mut TxContext) {
transfer::share_object(
Counter {
id: object::new(ctx),
collected_fees: balance::Balance<SUI>,
creator: address,
min_fee: u64,
}

/*
Init function that creates and shares a Counter object.

This function will be called once and only once during the package deployment.

Further reading:
- Shared objects: https://docs.sui.ioonceptsbject-ownershiphared
*/
fun init(ctx: &mut TxContext) {
transfer::share_object(Counter {
id: object::new(ctx),
count: 0,
}
);
}
collected_fees: balance::zero(),
creator: ctx.sender(),
min_fee: 10,
});
}

/*
Increment function that increases the counter value by 1.

This function takes a mutable reference to a Counter object and a SUI coin as fee.
The fee must be at least equal to the minimum fee set in the Counter object.
The fee is added to the collected_fees balance in the Counter.

Parameters:
- counter: Mutable reference to the Counter object to increment
- fee: SUI coin to pay as fee for incrementing

Aborts:
- If the fee is less than the minimum required fee
*/

public fun increment(counter: &mut Counter) {
public fun increment(counter: &mut Counter, fee: coin::Coin<SUI>) {
counter.count = counter.count + 1;
}
}
assert!(fee.value() >= counter.min_fee, 0);
counter.collected_fees.join(fee.into_balance());
}
74 changes: 0 additions & 74 deletions lessons/returning_objects/banana/sources/banana.move

This file was deleted.

37 changes: 0 additions & 37 deletions lessons/returning_objects/banana_without_display/Move.toml

This file was deleted.

This file was deleted.

Loading