-
Notifications
You must be signed in to change notification settings - Fork 290
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* move example for proxima fix move examples defi resource_groups update shared_account defi examples * update address
- Loading branch information
Showing
11 changed files
with
873 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "defi" | ||
version = "0.0.1" | ||
|
||
[addresses] | ||
defi = "0xed9ea1f3533c14e1b52d9ff6475776ba" | ||
|
||
[dependencies] | ||
StarcoinFramework = { local = "../../framework/starcoin-framework" } |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "hello-blockchain" | ||
version = "0.0.1" | ||
|
||
[addresses] | ||
hello_blockchain = "0xed9ea1f3533c14e1b52d9ff6475776ba" | ||
|
||
[dependencies] | ||
StarcoinFramework = { local = "../../framework/starcoin-framework" } |
59 changes: 59 additions & 0 deletions
59
vm/move-examples/hello_blockchain/sources/hello_blockchain.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
module hello_blockchain::message { | ||
use std::error; | ||
use std::signer; | ||
use std::string; | ||
use starcoin_framework::event; | ||
|
||
//:!:>resource | ||
struct MessageHolder has key { | ||
message: string::String, | ||
} | ||
//<:!:resource | ||
|
||
#[event] | ||
struct MessageChange has drop, store { | ||
account: address, | ||
from_message: string::String, | ||
to_message: string::String, | ||
} | ||
|
||
/// There is no message present | ||
const ENO_MESSAGE: u64 = 0; | ||
|
||
#[view] | ||
public fun get_message(addr: address): string::String acquires MessageHolder { | ||
assert!(exists<MessageHolder>(addr), error::not_found(ENO_MESSAGE)); | ||
borrow_global<MessageHolder>(addr).message | ||
} | ||
|
||
public entry fun set_message(account: signer, message: string::String) | ||
acquires MessageHolder { | ||
let account_addr = signer::address_of(&account); | ||
if (!exists<MessageHolder>(account_addr)) { | ||
move_to(&account, MessageHolder { | ||
message, | ||
}) | ||
} else { | ||
let old_message_holder = borrow_global_mut<MessageHolder>(account_addr); | ||
let from_message = old_message_holder.message; | ||
event::emit(MessageChange { | ||
account: account_addr, | ||
from_message, | ||
to_message: copy message, | ||
}); | ||
old_message_holder.message = message; | ||
} | ||
} | ||
|
||
#[test(account = @0x1)] | ||
public entry fun sender_can_set_message(account: signer) acquires MessageHolder { | ||
let addr = signer::address_of(&account); | ||
starcoin_framework::account::create_account_for_test(addr); | ||
set_message(account, string::utf8(b"Hello, Blockchain")); | ||
|
||
assert!( | ||
get_message(addr) == string::utf8(b"Hello, Blockchain"), | ||
ENO_MESSAGE | ||
); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
vm/move-examples/hello_blockchain/sources/hello_blockchain_test.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#[test_only] | ||
module hello_blockchain::message_tests { | ||
use std::signer; | ||
use std::unit_test; | ||
use std::vector; | ||
use std::string; | ||
|
||
use hello_blockchain::message; | ||
|
||
fun get_account(): signer { | ||
vector::pop_back(&mut unit_test::create_signers_for_testing(1)) | ||
} | ||
|
||
#[test] | ||
public entry fun sender_can_set_message() { | ||
let account = get_account(); | ||
let addr = signer::address_of(&account); | ||
starcoin_framework::account::create_account_for_test(addr); | ||
message::set_message(account, string::utf8(b"Hello, Blockchain")); | ||
|
||
assert!( | ||
message::get_message(addr) == string::utf8(b"Hello, Blockchain"), | ||
0 | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "ResourceGroupsPrimary" | ||
version = "0.0.1" | ||
|
||
[addresses] | ||
resource_groups_primary = "0xed9ea1f3533c14e1b52d9ff6475776ba" | ||
|
||
[dependencies] | ||
StarcoinFramework = { local = "../../../framework/starcoin-framework" } |
58 changes: 58 additions & 0 deletions
58
vm/move-examples/resource_groups/primary/sources/primary.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/// This demonstrates how to use a resource group within a single module | ||
/// See resource_groups_primary::secondary for cross module and multiple resources | ||
module resource_groups_primary::primary { | ||
use std::signer; | ||
|
||
#[resource_group(scope = global)] | ||
struct ResourceGroupContainer { } | ||
|
||
#[resource_group_member(group = resource_groups_primary::primary::ResourceGroupContainer)] | ||
struct Primary has drop, key { | ||
value: u64, | ||
} | ||
|
||
public entry fun init(account: &signer, value: u64) { | ||
move_to(account, Primary { value }); | ||
} | ||
|
||
public entry fun set_value(account: &signer, value: u64) acquires Primary { | ||
let primary = borrow_global_mut<Primary>(signer::address_of(account)); | ||
primary.value = value; | ||
} | ||
|
||
public fun read(account: address): u64 acquires Primary { | ||
borrow_global<Primary>(account).value | ||
} | ||
|
||
public entry fun remove(account: &signer) acquires Primary { | ||
move_from<Primary>(signer::address_of(account)); | ||
} | ||
|
||
public fun exists_at(account: address): bool { | ||
exists<Primary>(account) | ||
} | ||
|
||
fun init_module(owner: &signer) { | ||
move_to(owner, Primary { value: 3 }); | ||
} | ||
|
||
#[test(account = @0x3)] | ||
fun test_multiple(account: &signer) acquires Primary { | ||
// Do it once to verify normal flow | ||
test_primary(account); | ||
|
||
// Do it again to verify it can be recreated | ||
test_primary(account); | ||
} | ||
|
||
public fun test_primary(account: &signer) acquires Primary { | ||
let addr = signer::address_of(account); | ||
assert!(!exists_at(addr), 0); | ||
init(account, 5); | ||
assert!(read(addr) == 5, 1); | ||
set_value(account, 12); | ||
assert!(read(addr) == 12, 1); | ||
remove(account); | ||
assert!(!exists_at(addr), 0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "ResourceGroupsSecondary" | ||
version = "0.0.1" | ||
|
||
[addresses] | ||
resource_groups_primary = "0xed9ea1f3533c14e1b52d9ff6475776ba" | ||
resource_groups_secondary = "0xed9ea1f3533c14e1b52d9ff6475776ba" | ||
|
||
[dependencies] | ||
StarcoinFramework = { local = "../../../framework/starcoin-framework" } | ||
ResourceGroupsPrimary = { local = "../primary" } |
58 changes: 58 additions & 0 deletions
58
vm/move-examples/resource_groups/secondary/sources/secondary.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/// This demonstrates how to use a resource group accross modules | ||
module resource_groups_secondary::secondary { | ||
use std::signer; | ||
use resource_groups_primary::primary; | ||
|
||
#[resource_group_member(group = resource_groups_primary::primary::ResourceGroupContainer)] | ||
struct Secondary has drop, key { | ||
value: u32, | ||
} | ||
|
||
public entry fun init(account: &signer, value: u32) { | ||
move_to(account, Secondary { value }); | ||
} | ||
|
||
public entry fun set_value(account: &signer, value: u32) acquires Secondary { | ||
let primary = borrow_global_mut<Secondary>(signer::address_of(account)); | ||
primary.value = value; | ||
} | ||
|
||
public fun read(account: address): u32 acquires Secondary { | ||
borrow_global<Secondary>(account).value | ||
} | ||
|
||
public entry fun remove(account: &signer) acquires Secondary { | ||
move_from<Secondary>(signer::address_of(account)); | ||
} | ||
|
||
public fun exists_at(account: address): bool { | ||
exists<Secondary>(account) | ||
} | ||
|
||
// This boiler plate function exists just so that primary is loaded with secondary | ||
// We'll need to explore how to load resource_group_containers without necessarily | ||
// having loaded their module via the traditional module graph. | ||
public fun primary_exists(account: address): bool { | ||
primary::exists_at(account) | ||
} | ||
|
||
#[test(account = @0x3)] | ||
fun test_multiple(account: &signer) acquires Secondary { | ||
let addr = signer::address_of(account); | ||
assert!(!exists_at(addr), 0); | ||
init(account, 7); | ||
assert!(read(addr) == 7, 1); | ||
set_value(account, 13); | ||
assert!(read(addr) == 13, 1); | ||
|
||
// Verify that primary can be added and removed without affecting secondary | ||
primary::test_primary(account); | ||
assert!(read(addr) == 13, 1); | ||
|
||
remove(account); | ||
assert!(!exists_at(addr), 0); | ||
|
||
// Verify that primary can be re-added after secondary has been removed | ||
primary::test_primary(account); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "shared_account" | ||
version = "0.0.1" | ||
|
||
[addresses] | ||
shared_account = "0xed9ea1f3533c14e1b52d9ff6475776ba" | ||
|
||
[dependencies] | ||
StarcoinFramework = { local = "../../framework/starcoin-framework" } |
136 changes: 136 additions & 0 deletions
136
vm/move-examples/shared_account/sources/shared_account.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// This module demonstrates a basic shared account that could be used for NFT royalties | ||
// Users can (1) create a shared account (2) disperse the coins to multiple creators | ||
module shared_account::SharedAccount { | ||
use std::error; | ||
use std::signer; | ||
use std::vector; | ||
use starcoin_framework::account; | ||
use starcoin_framework::coin; | ||
|
||
// struct Share records the address of the share_holder and their corresponding number of shares | ||
struct Share has store { | ||
share_holder: address, | ||
num_shares: u64, | ||
} | ||
|
||
// Resource representing a shared account | ||
struct SharedAccount has key { | ||
share_record: vector<Share>, | ||
total_shares: u64, | ||
signer_capability: account::SignerCapability, | ||
} | ||
|
||
struct SharedAccountEvent has key { | ||
resource_addr: address, | ||
} | ||
|
||
const EACCOUNT_NOT_FOUND: u64 = 0; | ||
const ERESOURCE_DNE: u64 = 1; | ||
const EINSUFFICIENT_BALANCE: u64 = 2; | ||
|
||
// Create and initialize a shared account | ||
public entry fun initialize(source: &signer, seed: vector<u8>, addresses: vector<address>, numerators: vector<u64>) { | ||
let total = 0; | ||
let share_record = vector::empty<Share>(); | ||
|
||
vector::enumerate_ref(&addresses, |i, addr|{ | ||
let addr = *addr; | ||
let num_shares = *vector::borrow(&numerators, i); | ||
|
||
// make sure that the account exists, so when we call disperse() it wouldn't fail | ||
// because one of the accounts does not exist | ||
assert!(account::exists_at(addr), error::invalid_argument(EACCOUNT_NOT_FOUND)); | ||
|
||
vector::push_back(&mut share_record, Share { share_holder: addr, num_shares }); | ||
total = total + num_shares; | ||
}); | ||
|
||
let (resource_signer, resource_signer_cap) = account::create_resource_account(source, seed); | ||
|
||
move_to( | ||
&resource_signer, | ||
SharedAccount { | ||
share_record, | ||
total_shares: total, | ||
signer_capability: resource_signer_cap, | ||
} | ||
); | ||
|
||
move_to(source, SharedAccountEvent { | ||
resource_addr: signer::address_of(&resource_signer) | ||
}); | ||
} | ||
|
||
// Disperse all available balance to addresses in the shared account | ||
public entry fun disperse<CoinType>(resource_addr: address) acquires SharedAccount { | ||
assert!(exists<SharedAccount>(resource_addr), error::invalid_argument(ERESOURCE_DNE)); | ||
|
||
let total_balance = coin::balance<CoinType>(resource_addr); | ||
assert!(total_balance > 0, error::out_of_range(EINSUFFICIENT_BALANCE)); | ||
|
||
let shared_account = borrow_global<SharedAccount>(resource_addr); | ||
let resource_signer = account::create_signer_with_capability(&shared_account.signer_capability); | ||
|
||
vector::for_each_ref(&shared_account.share_record, |shared_record|{ | ||
let shared_record: &Share = shared_record; | ||
let current_amount = shared_record.num_shares * total_balance / shared_account.total_shares; | ||
coin::transfer<CoinType>(&resource_signer, shared_record.share_holder, current_amount); | ||
}); | ||
} | ||
|
||
#[test_only] | ||
public fun set_up(user: signer, test_user1: signer, test_user2: signer) : address acquires SharedAccountEvent { | ||
let addresses = vector::empty<address>(); | ||
let numerators = vector::empty<u64>(); | ||
let seed = x"01"; | ||
let user_addr = signer::address_of(&user); | ||
let user_addr1 = signer::address_of(&test_user1); | ||
let user_addr2 = signer::address_of(&test_user2); | ||
|
||
starcoin_framework::starcoin_account::create_account(user_addr); | ||
starcoin_framework::starcoin_account::create_account(user_addr1); | ||
starcoin_framework::starcoin_account::create_account(user_addr2); | ||
|
||
vector::push_back(&mut addresses, user_addr1); | ||
vector::push_back(&mut addresses, user_addr2); | ||
|
||
vector::push_back(&mut numerators, 1); | ||
vector::push_back(&mut numerators, 4); | ||
|
||
initialize(&user, seed, addresses, numerators); | ||
|
||
assert!(exists<SharedAccountEvent>(user_addr), error::not_found(EACCOUNT_NOT_FOUND)); | ||
borrow_global<SharedAccountEvent>(user_addr).resource_addr | ||
} | ||
|
||
#[test(user = @0x1111, test_user1 = @0x1112, test_user2 = @0x1113, core_framework = @starcoin_framework)] | ||
public entry fun test_disperse(user: signer, test_user1: signer, test_user2: signer, core_framework: signer) acquires SharedAccount, SharedAccountEvent { | ||
use starcoin_framework::starcoin_coin::{Self, STC}; | ||
let user_addr1 = signer::address_of(&test_user1); | ||
let user_addr2 = signer::address_of(&test_user2); | ||
let (burn_cap, mint_cap) = starcoin_coin::initialize_for_test(&core_framework); | ||
let resource_addr = set_up(user, test_user1, test_user2); | ||
|
||
let shared_account = borrow_global<SharedAccount>(resource_addr); | ||
let resource_signer = account::create_signer_with_capability(&shared_account.signer_capability); | ||
coin::register<STC>(&resource_signer); | ||
coin::deposit(resource_addr, coin::mint(1000, &mint_cap)); | ||
disperse<STC>(resource_addr); | ||
coin::destroy_mint_cap<STC>(mint_cap); | ||
coin::destroy_burn_cap<STC>(burn_cap); | ||
|
||
assert!(coin::balance<STC>(user_addr1) == 200, 0); | ||
assert!(coin::balance<STC>(user_addr2) == 800, 1); | ||
} | ||
|
||
#[test(user = @0x1111, test_user1 = @0x1112, test_user2 = @0x1113)] | ||
#[expected_failure] | ||
public entry fun test_disperse_insufficient_balance(user: signer, test_user1: signer, test_user2: signer) acquires SharedAccount, SharedAccountEvent { | ||
use starcoin_framework::starcoin_coin::STC; | ||
let resource_addr = set_up(user, test_user1, test_user2); | ||
let shared_account = borrow_global<SharedAccount>(resource_addr); | ||
let resource_signer = account::create_signer_with_capability(&shared_account.signer_capability); | ||
coin::register<STC>(&resource_signer); | ||
disperse<STC>(resource_addr); | ||
} | ||
} |