Skip to content

Commit

Permalink
[examples] Adds hot potato example (MystenLabs#3658)
Browse files Browse the repository at this point in the history
- adds hot potato example
  • Loading branch information
damirka authored Aug 16, 2022
1 parent 9097170 commit e809093
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 3 deletions.
2 changes: 1 addition & 1 deletion doc/book/examples/sources/basics/transfer.move
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module examples::profile {
}

/// Read `name` field from `ProfileInfo`.
public fun name(id: &ProfileInfo): &String {
public fun name(info: &ProfileInfo): &String {
&info.name
}

Expand Down
62 changes: 62 additions & 0 deletions doc/book/examples/sources/patterns/hot-potato.move
Original file line number Diff line number Diff line change
@@ -1,3 +1,65 @@
// Copyright (c) 2022, Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

module examples::trade_in {
use sui::transfer;
use sui::sui::SUI;
use sui::coin::{Self, Coin};
use sui::object::{Self, UID};
use sui::tx_context::{TxContext};

/// Price for the first phone model in series
const MODEL_ONE_PRICE: u64 = 10000;

/// Price for the second phone model
const MODEL_TWO_PRICE: u64 = 20000;

/// For when someone tries to purchase non-existing model
const EWrongModel: u64 = 1;

/// For when paid amount does not match the price
const EIncorrectAmount: u64 = 2;

/// A phone; can be purchased or traded in for a newer model
struct Phone has key, store { id: UID, model: u8 }

/// Payable receipt. Has to be paid directly or paid with a trade-in option.
/// Cannot be stored, owned or dropped - has to be used to select one of the
/// options for payment: `trade_in` or `pay_full`.
struct Receipt { price: u64 }

/// Get a phone, pay later.
/// Receipt has to be passed into one of the functions that accept it:
/// in this case it's `pay_full` or `trade_in`.
public fun buy_phone(model: u8, ctx: &mut TxContext): (Phone, Receipt) {
assert!(model == 1 || model == 2, EWrongModel);

let price = if (model == 1) MODEL_ONE_PRICE else MODEL_TWO_PRICE;

(
Phone { id: object::new(ctx), model },
Receipt { price }
)
}

/// Pay the full price for the phone and consume the `Receipt`.
public fun pay_full(receipt: Receipt, payment: Coin<SUI>) {
let Receipt { price } = receipt;
assert!(coin::value(&payment) == price, EIncorrectAmount);

// for simplicity's sake transfer directly to @examples account
transfer::transfer(payment, @examples);
}

/// Give back an old phone and get 50% of its price as a discount for the new one.
public fun trade_in(receipt: Receipt, old_phone: Phone, payment: Coin<SUI>) {
let Receipt { price } = receipt;
let tradein_price = if (old_phone.model == 1) MODEL_ONE_PRICE else MODEL_TWO_PRICE;
let to_pay = price - (tradein_price / 2);

assert!(coin::value(&payment) == to_pay, EIncorrectAmount);

transfer::transfer(old_phone, @examples);
transfer::transfer(payment, @examples);
}
}
2 changes: 1 addition & 1 deletion doc/book/examples/sources/patterns/witness.move
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module examples::guardian {
}

/// Custom module that makes use of the `guardian`.
module examples::peace {
module examples::peace_guardian {
use sui::transfer;
use sui::tx_context::{Self, TxContext};

Expand Down
2 changes: 1 addition & 1 deletion doc/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
- [Capability](./patterns/capability.md)
- [Witness](./patterns/witness.md)
- [Transferable Witness](./patterns/transferable-witness.md)
<!-- - [Hot Potato](./patterns/hot-potato.md) -->
- [Hot Potato](./patterns/hot-potato.md)
- [Samples](./samples/README.md)
- [Make an NFT](./samples/nft.md)
- [Create a Coin (ERC20)](./samples/coin.md)
Expand Down
2 changes: 2 additions & 0 deletions doc/book/src/patterns/hot-potato.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Hot Potato

Hot Potato is a name for a struct that has no abilities, hence it can only be packed and unpacked in its module. In this struct, you must call function B after function A in the case where function A returns a potato and function B consumes it.

```move
{{#include ../../examples/sources/patterns/hot-potato.move:4:}}
```

0 comments on commit e809093

Please sign in to comment.