Skip to content

Commit

Permalink
[hackathon] add tutorial for Move workshop
Browse files Browse the repository at this point in the history
  • Loading branch information
emmazzz authored and bors-libra committed Nov 30, 2021
1 parent 139acb2 commit 5f3bbcf
Show file tree
Hide file tree
Showing 28 changed files with 1,456 additions and 1 deletion.
599 changes: 599 additions & 0 deletions language/documentation/hackathon-tutorial/README.md

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions language/documentation/hackathon-tutorial/step_0/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) The Diem Core Contributors
# SPDX-License-Identifier: Apache-2.0

echo Installing dev dependencies
sh ${DIEM_HOME}/scripts/dev_setup.sh -yp
echo Installing Move CLI
cargo install --path ${DIEM_HOME}/diem-move/df-cli
echo Move CLI installed
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "BasicCoin"
version = "0.0.0"

[addresses]
NamedAddr = "0xDEADBEEF"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module NamedAddr::Coin {
struct Coin has key {
value: u64,
}

public fun mint(account: signer, value: u64) {
move_to(&account, Coin { value })
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "BasicCoin"
version = "0.0.0"

[addresses]
NamedAddr = "0xDEADBEEF"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module NamedAddr::Coin {
struct Coin has key {
value: u64,
}

public fun mint(account: signer, value: u64) {
move_to(&account, Coin { value })
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "BasicCoin"
version = "0.0.0"

[addresses]
NamedAddr = "0xDEADBEEF"

[dependencies]
MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "Std" = "0x1" } }
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module NamedAddr::Coin {
// Only included in compilation for testing. Similar to #[cfg(testing)]
// in Rust.
#[test_only]
use Std::Signer;

struct Coin has key {
value: u64,
}

public fun mint(account: signer, value: u64) {
move_to(&account, Coin { value })
}

// Declare a unit test. It takes a signer called `account` with an
// address value of `0xCAFE`.
#[test(account = @0xCAFE)]
fun test_mint_10(account: signer) acquires Coin {
let addr = Signer::address_of(&account);
mint(account, 10);
// Make sure there is a `Coin` resource under `addr` with a value of `10`.
// We can access this resource and its value since we are in the
// same module that defined the `Coin` resource.
assert!(borrow_global<Coin>(addr).value == 10, 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
mpm test -g

mpm test --coverage

Followed by:
mpm coverage summary
mpm coverage summary --summarize-functions
mpm coverage source --module Coin
22 changes: 22 additions & 0 deletions language/documentation/hackathon-tutorial/step_3/BasicCoin.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module NamedAddr::BasicCoin {
struct Coin has store {
value: u64
}

struct Balance has key {
coin: Coin
}

/// Publish an empty balance resource under `account`'s address. This function must be called before
/// minting or transferring to the account.
public fun publish_balance(account: &signer);

/// Mint `amount` tokens to `mint_addr`. Mint must be approved by the module owner.
public(script) fun mint(module_owner: signer, mint_addr: address, amount: u64) acquires Balance;

/// Returns the balance of `owner`.
public fun balance_of(owner: address): u64 acquires Balance;

/// Transfers `amount` of tokens from `from` to `to`.
public(script) fun transfer(from: signer, to: address, amount: u64) acquires Balance;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "BasicCoin"
version = "0.0.0"

[addresses]
NamedAddr = "0xDEADBEEF"

[dependencies]
MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "Std" = "0x1" } }
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/// This module defines a minimal Coin and Balance.
module NamedAddr::BasicCoin {
use Std::Errors;
use Std::Signer;

/// Address of the owner of this module
const MODULE_OWNER: address = @NamedAddr;

/// Error codes
const ENOT_MODULE_OWNER: u64 = 0;
const EINSUFFICIENT_BALANCE: u64 = 1;
const EALREADY_HAS_BALANCE: u64 = 2;

struct Coin has store {
value: u64
}

/// Struct representing the balance of each address.
struct Balance has key {
coin: Coin
}

/// Publish an empty balance resource under `account`'s address. This function must be called before
/// minting or transferring to the account.
public fun publish_balance(account: &signer) {
// TODO: add an assert to check that `account` doesn't already have a `Balance` resource.
let empty_coin = Coin { value: 0 };
move_to(account, Balance { coin: empty_coin });
}

/// Initialize this module.
public(script) fun mint(module_owner: signer, mint_addr: address, amount: u64) {
// Only the owner of the module can initialize this module
assert!(Signer::address_of(&module_owner) == MODULE_OWNER, Errors::requires_address(ENOT_MODULE_OWNER));

// Deposit `amount` of tokens to `mint_addr`'s balance
deposit(mint_addr, Coin { value: amount });
}

/// Returns the balance of `owner`.
public fun balance_of(owner: address): u64 acquires Balance {
borrow_global<Balance>(owner).coin.value
}

/// Transfers `amount` of tokens from `from` to `to`.
public(script) fun transfer(from: signer, to: address, amount: u64) acquires Balance {
let check = withdraw(Signer::address_of(&from), amount);
deposit(to, check);
}

/// Withdraw `amount` number of tokens from the balance under `addr`.
fun withdraw(addr: address, amount: u64) : Coin acquires Balance {
let balance = balance_of(addr);
// balance must be greater than the withdraw amount
assert!(balance >= amount, Errors::limit_exceeded(EINSUFFICIENT_BALANCE));
let balance_ref = &mut borrow_global_mut<Balance>(addr).coin.value;
*balance_ref = balance - amount;
Coin { value: amount }
}

/// Deposit `amount` number of tokens to the balance under `addr`.
fun deposit(_addr: address, check: Coin) {
// TODO: follow the implementation of `withdraw` and implement me!
let Coin { value: _amount } = check; // unpacks the check

// Get a mutable reference of addr's balance's coin value

// Increment the value by `amount`
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "BasicCoin"
version = "0.0.0"

[addresses]
NamedAddr = "0xDEADBEEF"

[dependencies]
MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "Std" = "0x1" } }
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/// This module defines a minimal Coin and Balance.
module NamedAddr::BasicCoin {
use Std::Errors;
use Std::Signer;

/// Address of the owner of this module
const MODULE_OWNER: address = @NamedAddr;

/// Error codes
const ENOT_MODULE_OWNER: u64 = 0;
const EINSUFFICIENT_BALANCE: u64 = 1;
const EALREADY_HAS_BALANCE: u64 = 2;

struct Coin has store {
value: u64
}

/// Struct representing the balance of each address.
struct Balance has key {
coin: Coin
}

/// Publish an empty balance resource under `account`'s address. This function must be called before
/// minting or transferring to the account.
public fun publish_balance(account: &signer) {
let empty_coin = Coin { value: 0 };
assert!(exists<Balance>(Signer::address_of(account)), Errors::already_published(EALREADY_HAS_BALANCE));
move_to(account, Balance { coin: empty_coin });
}

/// Mint `amount` tokens to `mint_addr`. Mint must be approved by the module owner.
public(script) fun mint(module_owner: signer, mint_addr: address, amount: u64) acquires Balance {
// Only the owner of the module can initialize this module
assert!(Signer::address_of(&module_owner) == MODULE_OWNER, Errors::requires_address(ENOT_MODULE_OWNER));

// Deposit `amount` of tokens to `mint_addr`'s balance
deposit(mint_addr, Coin { value: amount });
}

/// Returns the balance of `owner`.
public fun balance_of(owner: address): u64 acquires Balance {
borrow_global<Balance>(owner).coin.value
}

/// Transfers `amount` of tokens from `from` to `to`.
public(script) fun transfer(from: signer, to: address, amount: u64) acquires Balance {
let check = withdraw(Signer::address_of(&from), amount);
deposit(to, check);
}

/// Withdraw `amount` number of tokens from the balance under `addr`.
fun withdraw(addr: address, amount: u64) : Coin acquires Balance {
let balance = balance_of(addr);
// balance must be greater than the withdraw amount
assert!(balance >= amount, Errors::limit_exceeded(EINSUFFICIENT_BALANCE));
let balance_ref = &mut borrow_global_mut<Balance>(addr).coin.value;
*balance_ref = balance - amount;
Coin { value: amount }
}

/// Deposit `amount` number of tokens to the balance under `addr`.
fun deposit(addr: address, check: Coin) acquires Balance{
let balance = balance_of(addr);
let balance_ref = &mut borrow_global_mut<Balance>(addr).coin.value;
let Coin { value } = check;
*balance_ref = balance + value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "BasicCoin"
version = "0.0.0"

[addresses]
NamedAddr = "0xDEADBEEF"

[dependencies]
MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "Std" = "0x1" } }
Loading

0 comments on commit 5f3bbcf

Please sign in to comment.