From 254ff4119c70d86f5a77f319ddbbee08eb779d77 Mon Sep 17 00:00:00 2001 From: jolestar Date: Tue, 24 Oct 2023 15:54:13 +0800 Subject: [PATCH 01/18] [MoveosStd] Refactor ObjectRef, allow ObjectRef as transaction argument --- .../tests/cases/object/basic.exp | 18 +- .../tests/cases/object/basic.move | 15 +- .../tests/cases/object/object_cap.move | 20 +- .../tests/cases/table/basic.exp | 6 +- .../tests/cases/table/basic.move | 30 ++- .../tests/cases/table/test_destroy.exp | 12 +- .../tests/cases/table/test_destroy.move | 16 +- .../rooch-framework/doc/account_coin_store.md | 7 +- crates/rooch-framework/doc/coin_store.md | 81 +-------- .../sources/account_coin_store.move | 7 +- .../rooch-framework/sources/coin_store.move | 39 +--- .../moveos-stdlib/doc/account_storage.md | 5 +- .../moveos-stdlib/doc/context.md | 61 +++---- .../moveos-stdlib/moveos-stdlib/doc/event.md | 1 - .../moveos-stdlib/moveos-stdlib/doc/object.md | 70 ++++++- .../moveos-stdlib/doc/object_ref.md | 140 ++++++++------ .../sources/account_storage.move | 4 +- .../moveos-stdlib/sources/context.move | 40 ++-- .../moveos-stdlib/sources/event.move | 6 +- .../moveos-stdlib/sources/object.move | 16 +- .../moveos-stdlib/sources/object_ref.move | 55 +++--- .../sources/storage_context.move | 10 +- .../src/natives/moveos_stdlib/move_module.rs | 6 +- moveos/moveos-types/src/state.rs | 19 ++ moveos/moveos-verifier/src/metadata.rs | 1 + moveos/moveos-verifier/src/verifier.rs | 40 ++-- moveos/moveos/src/vm/moveos_vm.rs | 52 ++---- moveos/moveos/src/vm/tx_argument_resolver.rs | 172 +++++++++++++----- 28 files changed, 518 insertions(+), 431 deletions(-) diff --git a/crates/rooch-framework-tests/tests/cases/object/basic.exp b/crates/rooch-framework-tests/tests/cases/object/basic.exp index fbfee54657..80f6ddeaea 100644 --- a/crates/rooch-framework-tests/tests/cases/object/basic.exp +++ b/crates/rooch-framework-tests/tests/cases/object/basic.exp @@ -1,32 +1,32 @@ processed 10 tasks -task 1 'publish'. lines 3-40: +task 1 'publish'. lines 3-45: status EXECUTED -task 2 'run'. lines 42-42: +task 2 'run'. lines 47-47: status EXECUTED -task 3 'view_object'. lines 44-46: +task 3 'view_object'. lines 49-51: Object { id: ObjectID(ae43e34e51db9c833ab50dd9aa8b27106519e5bbfd533737306e7b69ef253647), owner: 0000000000000000000000000000000000000000000000000000000000000043, value: AnnotatedMoveStruct { abilities: [Store, Key, ], type_: StructTag { address: 0000000000000000000000000000000000000000000000000000000000000042, module: Identifier("m"), name: Identifier("S"), type_params: [] }, value: [(Identifier("v"), U8(1))] } } -task 4 'run'. lines 48-48: +task 4 'run'. lines 53-53: status EXECUTED -task 5 'view_object'. lines 50-53: +task 5 'view_object'. lines 55-58: Object { id: ObjectID(0bbaf311ae6768a532b1f9dee65b1758a7bb1114fd57df8fa94cb2d1cb5f6896), owner: 0000000000000000000000000000000000000000000000000000000000000043, value: AnnotatedMoveStruct { abilities: [Store, Key, ], type_: StructTag { address: 0000000000000000000000000000000000000000000000000000000000000042, module: Identifier("m"), name: Identifier("Cup"), type_params: [Struct(StructTag { address: 0000000000000000000000000000000000000000000000000000000000000042, module: Identifier("m"), name: Identifier("S"), type_params: [] })] }, value: [(Identifier("v"), U8(2))] } } -task 6 'run'. lines 55-55: +task 6 'run'. lines 60-60: status EXECUTED -task 7 'view'. lines 57-59: +task 7 'view'. lines 62-64: store key 0x42::m::S { v: 1u8 } -task 8 'run'. lines 61-61: +task 8 'run'. lines 66-66: status EXECUTED -task 9 'view'. lines 63-63: +task 9 'view'. lines 68-68: store key 0x42::m::Cup<0x42::m::S> { v: 2u8 } diff --git a/crates/rooch-framework-tests/tests/cases/object/basic.move b/crates/rooch-framework-tests/tests/cases/object/basic.move index 5a4548d310..904ac49c27 100644 --- a/crates/rooch-framework-tests/tests/cases/object/basic.move +++ b/crates/rooch-framework-tests/tests/cases/object/basic.move @@ -4,7 +4,7 @@ module test::m { use moveos_std::context::{Self, Context}; - use moveos_std::object::ObjectID; + use moveos_std::object_ref::{Self, ObjectRef}; use moveos_std::account_storage; use std::debug; @@ -17,22 +17,27 @@ module test::m { // if the tx hash change, need to figure out why. assert!(x"7852c5dcbd87e82102dba0db36d44b5a9fb0006b3e828c0b5f0832f70a8ff6ee" == tx_hash, 1000); let obj_ref = context::new_object(ctx, S { v: 1}); + let sender = context::sender(ctx); debug::print(&obj_ref); + object_ref::to_user_owner(obj_ref, sender); } - public entry fun move_s_to_global(ctx: &mut Context, sender: signer, object_id: ObjectID) { + public entry fun move_s_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef) { + let object_id = object_ref::id(&object_s); debug::print(&object_id); - let (_id, _owner, value) = context::remove_object(ctx, object_id); + let value = object_ref::remove(object_s); account_storage::global_move_to(ctx, &sender, value); } public entry fun mint_cup(ctx: &mut Context) { let obj_ref = context::new_object(ctx, Cup { v: 2 }); debug::print(&obj_ref); + let sender = context::sender(ctx); + object_ref::to_user_owner(obj_ref, sender); } - public entry fun move_cup_to_global(ctx: &mut Context, sender: signer, object_id: ObjectID) { - let (_id,_owner,value) = context::remove_object>(ctx, object_id); + public entry fun move_cup_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef>) { + let value = object_ref::remove(object_s); account_storage::global_move_to(ctx, &sender, value); } } diff --git a/crates/rooch-framework-tests/tests/cases/object/object_cap.move b/crates/rooch-framework-tests/tests/cases/object/object_cap.move index 5912d197ac..3dcefcba88 100644 --- a/crates/rooch-framework-tests/tests/cases/object/object_cap.move +++ b/crates/rooch-framework-tests/tests/cases/object/object_cap.move @@ -3,18 +3,18 @@ //# publish module test::m { - struct TestObject has key{ + struct TestStruct has key{ f: u8 } - public fun new_test_object(f: u8): TestObject { - TestObject{ + public fun new_test_struct(f: u8): TestStruct { + TestStruct{ f, } } - public fun destroy_test_object(test_object: TestObject) { - let TestObject{f : _f} = test_object; + public fun destroy_test_struct(test_struct: TestStruct) { + let TestStruct{f : _f} = test_struct; } } @@ -23,13 +23,13 @@ module test::m { script { use moveos_std::context::{Self, Context}; use moveos_std::object_ref; - use test::m::{Self, TestObject}; + use test::m::{Self, TestStruct}; fun main(ctx: &mut Context) { - let object = m::new_test_object(12); - let obj_ref = context::new_object(ctx, object); - let (_id, _owner, test_object) = context::remove_object(ctx, object_ref::id(&obj_ref)); - m::destroy_test_object(test_object); + let object = m::new_test_struct(12); + let obj_ref = context::new_object(ctx, object); + let test_struct = object_ref::remove(obj_ref); + m::destroy_test_struct(test_struct); } } diff --git a/crates/rooch-framework-tests/tests/cases/table/basic.exp b/crates/rooch-framework-tests/tests/cases/table/basic.exp index 97bb346f29..5ded103c9f 100644 --- a/crates/rooch-framework-tests/tests/cases/table/basic.exp +++ b/crates/rooch-framework-tests/tests/cases/table/basic.exp @@ -1,10 +1,10 @@ processed 4 tasks -task 1 'publish'. lines 3-42: +task 1 'publish'. lines 3-39: status EXECUTED -task 2 'run'. lines 44-56: +task 2 'run'. lines 41-53: status EXECUTED -task 3 'run'. lines 58-71: +task 3 'run'. lines 55-67: status EXECUTED diff --git a/crates/rooch-framework-tests/tests/cases/table/basic.move b/crates/rooch-framework-tests/tests/cases/table/basic.move index de04e6c571..b500aa1b91 100644 --- a/crates/rooch-framework-tests/tests/cases/table/basic.move +++ b/crates/rooch-framework-tests/tests/cases/table/basic.move @@ -5,9 +5,8 @@ module test::m { use std::string::String; use moveos_std::table::{Self, Table}; use moveos_std::context::{Self, Context}; - use moveos_std::object; use moveos_std::object::ObjectID; - use moveos_std::object_ref::{ObjectRef}; + use moveos_std::object_ref; struct KVStore has store, key { table: Table>, @@ -31,13 +30,11 @@ module test::m { table::borrow(&store.table, key) } - public fun save_to_object_storage(ctx: &mut Context, kv: KVStore) : ObjectRef { - context::new_object(ctx, kv) - } - - public fun borrow_from_object_storage(ctx: &mut Context, object_id: ObjectID): &KVStore { - let object = context::borrow_object(ctx, object_id); - object::borrow(object) + public fun save_to_object_storage(ctx: &mut Context, kv: KVStore) : ObjectID { + let object_ref = context::new_object(ctx, kv); + let object_id = object_ref::id(&object_ref); + object_ref::to_user_owner(object_ref, context::sender(ctx)); + object_id } } @@ -50,20 +47,19 @@ script { fun main(ctx: &mut Context) { let kv = m::make_kv_store(ctx); m::add(&mut kv, string::utf8(b"test"), b"value"); - let object_ref = m::save_to_object_storage(ctx, kv); - std::debug::print(&object_ref); + let object_id = m::save_to_object_storage(ctx, kv); + std::debug::print(&object_id); } } -//# run --signers test --args @0xcc48c91b1a0f15813bed988390a2794660ae5dadcd86fdb1b55d4a28d0f74c4d +//# run --signers test --args @0x1a2c876ea44c751aedab69ef139181114c79abf4fb8bca363b66969218e7d815 script { use std::string; - use moveos_std::context::{Context}; - use moveos_std::object::ObjectID; - use test::m; + use moveos_std::object_ref::{Self, ObjectRef}; + use test::m::{Self, KVStore}; - fun main(ctx: &mut Context, object_id: ObjectID) { - let kv = m::borrow_from_object_storage(ctx, object_id); + fun main(kv_object: &ObjectRef) { + let kv = object_ref::borrow(kv_object); assert!(m::contains(kv, string::utf8(b"test")), 1000); let v = m::borrow(kv, string::utf8(b"test")); assert!(v == &b"value", 1001); diff --git a/crates/rooch-framework-tests/tests/cases/table/test_destroy.exp b/crates/rooch-framework-tests/tests/cases/table/test_destroy.exp index c3d4b9613e..51d5fbb100 100644 --- a/crates/rooch-framework-tests/tests/cases/table/test_destroy.exp +++ b/crates/rooch-framework-tests/tests/cases/table/test_destroy.exp @@ -1,19 +1,19 @@ processed 7 tasks -task 1 'publish'. lines 3-76: +task 1 'publish'. lines 3-64: status EXECUTED -task 2 'run'. lines 78-92: +task 2 'run'. lines 66-80: status EXECUTED -task 3 'run'. lines 93-108: +task 3 'run'. lines 81-96: status EXECUTED -task 4 'run'. lines 109-124: +task 4 'run'. lines 97-112: status EXECUTED -task 5 'run'. lines 125-137: +task 5 'run'. lines 113-125: status ABORTED with code 4 in 0000000000000000000000000000000000000000000000000000000000000002::raw_table -task 6 'run'. lines 138-151: +task 6 'run'. lines 126-139: status EXECUTED diff --git a/crates/rooch-framework-tests/tests/cases/table/test_destroy.move b/crates/rooch-framework-tests/tests/cases/table/test_destroy.move index 0fefb07321..720e65762f 100644 --- a/crates/rooch-framework-tests/tests/cases/table/test_destroy.move +++ b/crates/rooch-framework-tests/tests/cases/table/test_destroy.move @@ -4,10 +4,7 @@ module test::m { use std::string::String; use moveos_std::table::{Self, Table}; - use moveos_std::context::{Self, Context}; - use moveos_std::object; - use moveos_std::object_ref::{ObjectRef}; - use moveos_std::object::ObjectID; + use moveos_std::context::{Context}; use moveos_std::account_storage; struct KVStore has store, key { @@ -35,16 +32,7 @@ module test::m { public fun borrow(store: &KVStore, key: String): &vector { table::borrow(&store.table, key) } - - public fun save_to_object_storage(ctx: &mut Context, kv: KVStore) : ObjectRef { - context::new_object(ctx, kv) - } - - public fun borrow_from_object_storage(ctx: &mut Context, object_id: ObjectID): &KVStore { - let object = context::borrow_object(ctx, object_id); - object::borrow(object) - } - + public fun save_to_account_storage(ctx: &mut Context, account: &signer, store: KVStore){ account_storage::global_move_to(ctx, account, store); } diff --git a/crates/rooch-framework/doc/account_coin_store.md b/crates/rooch-framework/doc/account_coin_store.md index 40391ddc9b..d7a5036c75 100644 --- a/crates/rooch-framework/doc/account_coin_store.md +++ b/crates/rooch-framework/doc/account_coin_store.md @@ -301,10 +301,9 @@ Returns the balance of addr for provided CoinType.
public fun balance<CoinType: key>(ctx: &Context, addr: address): u256 {
-    let coin_store_id_option = coin_store_id<CoinType>(ctx, addr);
-    if (option::is_some(&coin_store_id_option)) {
-        let coin_store_id = option::extract(&mut coin_store_id_option);
-        coin_store::get_balance_with_id(ctx, coin_store_id)
+    if(exist_account_coin_store<CoinType>(ctx, addr)) {
+        let coin_store = borrow_account_coin_store<CoinType>(ctx, addr);
+        coin_store::balance(coin_store)
     } else {
         0u256
     }
diff --git a/crates/rooch-framework/doc/coin_store.md b/crates/rooch-framework/doc/coin_store.md
index 2ae5240d7a..46eb7844ec 100644
--- a/crates/rooch-framework/doc/coin_store.md
+++ b/crates/rooch-framework/doc/coin_store.md
@@ -16,8 +16,6 @@
 -  [Function `is_frozen`](#0x3_coin_store_is_frozen)
 -  [Function `withdraw`](#0x3_coin_store_withdraw)
 -  [Function `deposit`](#0x3_coin_store_deposit)
--  [Function `is_coin_store_frozen`](#0x3_coin_store_is_coin_store_frozen)
--  [Function `get_balance_with_id`](#0x3_coin_store_get_balance_with_id)
 -  [Function `freeze_coin_store_extend`](#0x3_coin_store_freeze_coin_store_extend)
 -  [Function `create_coin_store_internal`](#0x3_coin_store_create_coin_store_internal)
 
@@ -69,7 +67,7 @@ A holder of a specific coin types.
 These are kept in a single resource to ensure locality of data.
 
 
-
struct CoinStore has key
+
struct CoinStore has store, key
 
@@ -349,68 +347,6 @@ Deposit amount Coin to the balance of the passed-in - - - -## Function `is_coin_store_frozen` - -Get if the CoinStore is frozen via the coin store id - - -
public fun is_coin_store_frozen(ctx: &context::Context, coin_store_id: object::ObjectID): bool
-
- - - -
-Implementation - - -
public fun is_coin_store_frozen(ctx: &Context, coin_store_id: ObjectID): bool {
-    if (context::exist_object(ctx, coin_store_id)){
-        let coin_store_object = context::borrow_object<CoinStore>(ctx, coin_store_id);
-        object::borrow(coin_store_object).frozen
-    }else{
-        //TODO if the coin store is not exist, should we return true or false?
-        false
-    }
-}
-
- - - -
- - - -## Function `get_balance_with_id` - -Get the balance of the CoinStore with the coin store id -If the CoinStore is not exist, return 0 - - -
public fun get_balance_with_id(ctx: &context::Context, coin_store_id: object::ObjectID): u256
-
- - - -
-Implementation - - -
public fun get_balance_with_id(ctx: &Context, coin_store_id: ObjectID): u256 {
-    if (context::exist_object(ctx, coin_store_id)){
-        let coin_store_object = context::borrow_object<CoinStore>(ctx, coin_store_id);
-        object::borrow(coin_store_object).balance.value
-    }else{
-        0u256
-    }
-}
-
- - -
@@ -422,7 +358,7 @@ This function is for he CoinType module to extend, Only the CoinType module can freeze or unfreeze a CoinStore by the coin store id -
public fun freeze_coin_store_extend<CoinType: key>(ctx: &mut context::Context, coin_store_id: object::ObjectID, frozen: bool)
+
public fun freeze_coin_store_extend<CoinType: key>(_ctx: &mut context::Context, _coin_store_id: object::ObjectID, _frozen: bool)
 
@@ -432,13 +368,14 @@ Only the CoinType module can freeze or unfreeze a CoinStore by the
public fun freeze_coin_store_extend<CoinType: key>(
-    ctx: &mut Context,
-    coin_store_id: ObjectID,
-    frozen: bool,
+    _ctx: &mut Context,
+    _coin_store_id: ObjectID,
+    _frozen: bool,
 ) {
-    assert!(context::exist_object(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound));
-    let coin_store_object = context::borrow_object_mut<CoinStore>(ctx, coin_store_id);
-    object::borrow_mut(coin_store_object).frozen = frozen;
+    //TODO how to provide freeze coin store via coin store id
+    // assert!(context::exist_object(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound));
+    // let coin_store_object = context::borrow_object_mut<CoinStore>(ctx, coin_store_id);
+    // object::borrow_mut(coin_store_object).frozen = frozen;
 }
 
diff --git a/crates/rooch-framework/sources/account_coin_store.move b/crates/rooch-framework/sources/account_coin_store.move index d1b775ccef..5149e3334c 100644 --- a/crates/rooch-framework/sources/account_coin_store.move +++ b/crates/rooch-framework/sources/account_coin_store.move @@ -82,10 +82,9 @@ module rooch_framework::account_coin_store { /// Returns the balance of `addr` for provided `CoinType`. public fun balance(ctx: &Context, addr: address): u256 { - let coin_store_id_option = coin_store_id(ctx, addr); - if (option::is_some(&coin_store_id_option)) { - let coin_store_id = option::extract(&mut coin_store_id_option); - coin_store::get_balance_with_id(ctx, coin_store_id) + if(exist_account_coin_store(ctx, addr)) { + let coin_store = borrow_account_coin_store(ctx, addr); + coin_store::balance(coin_store) } else { 0u256 } diff --git a/crates/rooch-framework/sources/coin_store.move b/crates/rooch-framework/sources/coin_store.move index 65fb064518..46c3c13104 100644 --- a/crates/rooch-framework/sources/coin_store.move +++ b/crates/rooch-framework/sources/coin_store.move @@ -5,7 +5,7 @@ module rooch_framework::coin_store { use std::string; use std::error; - use moveos_std::object::{Self, ObjectID}; + use moveos_std::object::{ObjectID}; use moveos_std::context::{Self, Context}; use moveos_std::type_info; use moveos_std::object_ref::{ObjectRef}; @@ -35,7 +35,7 @@ module rooch_framework::coin_store { /// A holder of a specific coin types. /// These are kept in a single resource to ensure locality of data. - struct CoinStore has key { + struct CoinStore has key,store { coin_type: string::String, balance: Balance, frozen: bool, @@ -91,40 +91,19 @@ module rooch_framework::coin_store { merge_to_balance(coin_store, coin); } - /// Get if the CoinStore is frozen via the coin store id - public fun is_coin_store_frozen(ctx: &Context, coin_store_id: ObjectID): bool { - if (context::exist_object(ctx, coin_store_id)){ - let coin_store_object = context::borrow_object(ctx, coin_store_id); - object::borrow(coin_store_object).frozen - }else{ - //TODO if the coin store is not exist, should we return true or false? - false - } - } - - /// Get the balance of the CoinStore with the coin store id - /// If the CoinStore is not exist, return 0 - public fun get_balance_with_id(ctx: &Context, coin_store_id: ObjectID): u256 { - if (context::exist_object(ctx, coin_store_id)){ - let coin_store_object = context::borrow_object(ctx, coin_store_id); - object::borrow(coin_store_object).balance.value - }else{ - 0u256 - } - } - #[private_generics(CoinType)] /// Freeze or Unfreeze a CoinStore to prevent withdraw and desposit /// This function is for he `CoinType` module to extend, /// Only the `CoinType` module can freeze or unfreeze a CoinStore by the coin store id public fun freeze_coin_store_extend( - ctx: &mut Context, - coin_store_id: ObjectID, - frozen: bool, + _ctx: &mut Context, + _coin_store_id: ObjectID, + _frozen: bool, ) { - assert!(context::exist_object(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound)); - let coin_store_object = context::borrow_object_mut(ctx, coin_store_id); - object::borrow_mut(coin_store_object).frozen = frozen; + //TODO how to provide freeze coin store via coin store id + // assert!(context::exist_object(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound)); + // let coin_store_object = context::borrow_object_mut(ctx, coin_store_id); + // object::borrow_mut(coin_store_object).frozen = frozen; } // Internal functions diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md b/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md index 6cc32b346c..d8216984e5 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md @@ -31,7 +31,6 @@ It is used to store the account's resources and modules use 0x2::context; use 0x2::move_module; use 0x2::object; -use 0x2::object_ref; use 0x2::table; use 0x2::tx_context; use 0x2::type_table; @@ -199,8 +198,8 @@ Create a new account storage space resources: type_table::new_with_id(named_table_id(account, NamedTableResource)), modules: table::new_with_id(named_table_id(account, NamedTableModule)), }; - //Should we keep the storage ref? - let _account_storage_ref = context::new_object_with_id(ctx, object_id, account, account_storage); + let obj = object::new(object_id, account_storage); + context::add_object(ctx, obj); }
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md index 238f5472f0..d56af20306 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md @@ -24,9 +24,9 @@ and let developers customize the storage - [Function `borrow_object`](#0x2_context_borrow_object) - [Function `borrow_object_mut`](#0x2_context_borrow_object_mut) - [Function `remove_object`](#0x2_context_remove_object) +- [Function `add_object`](#0x2_context_add_object) - [Function `exist_object`](#0x2_context_exist_object) - [Function `new_object`](#0x2_context_new_object) -- [Function `new_object_with_owner`](#0x2_context_new_object_with_owner) - [Function `new_object_with_id`](#0x2_context_new_object_with_id) - [Function `new_singleton_object`](#0x2_context_new_singleton_object) @@ -38,7 +38,6 @@ and let developers customize the storage use 0x2::tx_context; use 0x2::tx_meta; use 0x2::tx_result; -use 0x2::type_info;
@@ -386,7 +385,7 @@ Get a value from the context map Borrow Object from object store with object_id -
public fun borrow_object<T: key>(self: &context::Context, object_id: object::ObjectID): &object::Object<T>
+
public(friend) fun borrow_object<T: key>(self: &context::Context, object_id: object::ObjectID): &object::Object<T>
 
@@ -395,7 +394,7 @@ Borrow Object from object store with object_id Implementation -
public fun borrow_object<T: key>(self: &Context, object_id: ObjectID): &Object<T> {
+
public(friend) fun borrow_object<T: key>(self: &Context, object_id: ObjectID): &Object<T> {
     storage_context::borrow<T>(&self.storage_context, object_id)
 }
 
@@ -411,7 +410,7 @@ Borrow Object from object store with object_id Borrow mut Object from object store with object_id -
public fun borrow_object_mut<T: key>(self: &mut context::Context, object_id: object::ObjectID): &mut object::Object<T>
+
public(friend) fun borrow_object_mut<T: key>(self: &mut context::Context, object_id: object::ObjectID): &mut object::Object<T>
 
@@ -420,7 +419,7 @@ Borrow mut Object from object store with object_id Implementation -
public fun borrow_object_mut<T: key>(self: &mut Context, object_id: ObjectID): &mut Object<T> {
+
public(friend) fun borrow_object_mut<T: key>(self: &mut Context, object_id: ObjectID): &mut Object<T> {
     storage_context::borrow_mut<T>(&mut self.storage_context, object_id)
 }
 
@@ -436,7 +435,7 @@ Borrow mut Object from object store with object_id Remove object from object store, and unpack the Object -
public fun remove_object<T: key>(self: &mut context::Context, object_id: object::ObjectID): (object::ObjectID, address, T)
+
public(friend) fun remove_object<T: key>(self: &mut context::Context, object_id: object::ObjectID): (object::ObjectID, address, T)
 
@@ -445,7 +444,7 @@ Remove object from object store, and unpack the Object Implementation -
public fun remove_object<T: key>(self: &mut Context, object_id: ObjectID): (ObjectID, address, T) {
+
public(friend) fun remove_object<T: key>(self: &mut Context, object_id: ObjectID): (ObjectID, address, T) {
     let obj = storage_context::remove<T>(&mut self.storage_context, object_id);
     object::unpack_internal(obj)
 }
@@ -455,13 +454,13 @@ Remove object from object store, and unpack the Object
 
 
 
-
+
 
-## Function `exist_object`
+## Function `add_object`
 
 
 
-
public fun exist_object(self: &context::Context, object_id: object::ObjectID): bool
+
public(friend) fun add_object<T: key>(self: &mut context::Context, object: object::Object<T>)
 
@@ -470,8 +469,8 @@ Remove object from object store, and unpack the Object Implementation -
public fun exist_object(self: &Context, object_id: ObjectID): bool {
-    storage_context::contains(&self.storage_context, object_id)
+
public(friend) fun add_object<T: key>(self: &mut Context, object: Object<T>) {
+    storage_context::add(&mut self.storage_context, object);
 }
 
@@ -479,15 +478,13 @@ Remove object from object store, and unpack the Object - + -## Function `new_object` +## Function `exist_object` -Create a new Object, the owner is the sender -Add the Object to the global object storage and return the ObjectRef -
public fun new_object<T: key>(self: &mut context::Context, value: T): object_ref::ObjectRef<T>
+
public(friend) fun exist_object(self: &context::Context, object_id: object::ObjectID): bool
 
@@ -496,10 +493,8 @@ Add the Object to the global object storage and return the ObjectRef Implementation -
public fun new_object<T: key>(self: &mut Context, value: T): ObjectRef<T> {
-    let id = fresh_object_id(self);
-    let owner = sender(self);
-    new_object_with_id(self, id, owner, value)
+
public(friend) fun exist_object(self: &Context, object_id: ObjectID): bool {
+    storage_context::contains(&self.storage_context, object_id)
 }
 
@@ -507,15 +502,15 @@ Add the Object to the global object storage and return the ObjectRef - + -## Function `new_object_with_owner` +## Function `new_object` -Create a new Object with owner +Create a new Object, the owner is the sender Add the Object to the global object storage and return the ObjectRef -
public fun new_object_with_owner<T: key>(self: &mut context::Context, owner: address, value: T): object_ref::ObjectRef<T>
+
public fun new_object<T: key>(self: &mut context::Context, value: T): object_ref::ObjectRef<T>
 
@@ -524,9 +519,9 @@ Add the Object to the global object storage and return the ObjectRef Implementation -
public fun new_object_with_owner<T: key>(self: &mut Context, owner: address, value: T): ObjectRef<T> {
-    let object_id = fresh_object_id(self);
-    new_object_with_id(self, object_id, owner, value)
+
public fun new_object<T: key>(self: &mut Context, value: T): ObjectRef<T> {
+    let id = fresh_object_id(self);
+    new_object_with_id(self, id, value)
 }
 
@@ -540,7 +535,7 @@ Add the Object to the global object storage and return the ObjectRef -
public(friend) fun new_object_with_id<T: key>(self: &mut context::Context, id: object::ObjectID, owner: address, value: T): object_ref::ObjectRef<T>
+
public(friend) fun new_object_with_id<T: key>(self: &mut context::Context, id: object::ObjectID, value: T): object_ref::ObjectRef<T>
 
@@ -549,8 +544,8 @@ Add the Object to the global object storage and return the ObjectRef Implementation -
public(friend) fun new_object_with_id<T: key>(self: &mut Context, id: ObjectID, owner: address, value: T) : ObjectRef<T> {
-    let obj = object::new(id, owner, value);
+
public(friend) fun new_object_with_id<T: key>(self: &mut Context, id: ObjectID, value: T) : ObjectRef<T> {
+    let obj = object::new(id, value);
     let obj_ref = object_ref::new_internal(&mut obj);
     storage_context::add(&mut self.storage_context, obj);
     obj_ref
@@ -578,7 +573,7 @@ Add the Object to the global object storage and return the ObjectRef
 
 
public fun new_singleton_object<T: key>(self: &mut Context, value: T): ObjectRef<T> {
     let object_id = object::singleton_object_id<T>();
-    new_object_with_id(self, object_id, type_info::account_address(&type_info::type_of<T>()), value)
+    new_object_with_id(self, object_id, value)
 }
 
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/event.md b/moveos/moveos-stdlib/moveos-stdlib/doc/event.md index 5af4bb1158..3b44907403 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/event.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/event.md @@ -19,7 +19,6 @@ events emitted to a handle and emit events to the event store. use 0x2::bcs; use 0x2::context; use 0x2::object; -use 0x2::object_ref; use 0x2::type_info;
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md index 0908662a47..0658f145cf 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md @@ -12,13 +12,16 @@ The differents with the Object in [Sui](https://github.com/MystenLabs/sui/blob/5 - [Struct `Object`](#0x2_object_Object) - [Struct `ObjectID`](#0x2_object_ObjectID) +- [Constants](#@Constants_0) - [Function `address_to_object_id`](#0x2_object_address_to_object_id) - [Function `singleton_object_id`](#0x2_object_singleton_object_id) +- [Function `code_owner_address`](#0x2_object_code_owner_address) - [Function `new`](#0x2_object_new) - [Function `borrow`](#0x2_object_borrow) - [Function `internal_borrow`](#0x2_object_internal_borrow) - [Function `borrow_mut`](#0x2_object_borrow_mut) - [Function `internal_borrow_mut`](#0x2_object_internal_borrow_mut) +- [Function `set_owner`](#0x2_object_set_owner) - [Function `transfer`](#0x2_object_transfer) - [Function `id`](#0x2_object_id) - [Function `owner`](#0x2_object_owner) @@ -103,6 +106,20 @@ An object ID + + +## Constants + + + + + + +
const CODE_OWNER_ADDRESS: address = 0;
+
+ + + ## Function `address_to_object_id` @@ -158,6 +175,30 @@ Generate a new ObjectID from an address + + + + +## Function `code_owner_address` + + + +
public fun code_owner_address(): address
+
+ + + +
+Implementation + + +
public fun code_owner_address(): address {
+    CODE_OWNER_ADDRESS
+}
+
+ + +
@@ -167,7 +208,7 @@ Generate a new ObjectID from an address Create a new object, the object is owned by owner -
public(friend) fun new<T: key>(id: object::ObjectID, owner: address, value: T): object::Object<T>
+
public(friend) fun new<T: key>(id: object::ObjectID, value: T): object::Object<T>
 
@@ -176,7 +217,8 @@ Create a new object, the object is owned by owner Implementation -
public(friend) fun new<T: key>(id: ObjectID, owner: address, value: T): Object<T> {
+
public(friend) fun new<T: key>(id: ObjectID, value: T): Object<T> {
+    let owner = CODE_OWNER_ADDRESS;
     Object<T>{id, value, owner}
 }
 
@@ -280,6 +322,30 @@ Borrow the mutable object value + + + + +## Function `set_owner` + + + +
public(friend) fun set_owner<T>(self: &mut object::Object<T>, owner: address)
+
+ + + +
+Implementation + + +
public(friend) fun set_owner<T>(self: &mut Object<T>, owner: address) {
+    self.owner = owner;
+}
+
+ + +
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md index b858c4feae..cc3a5b484a 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md @@ -6,15 +6,16 @@ - [Resource `ObjectRef`](#0x2_object_ref_ObjectRef) -- [Function `new`](#0x2_object_ref_new) - [Function `new_internal`](#0x2_object_ref_new_internal) +- [Function `to_user_owner`](#0x2_object_ref_to_user_owner) - [Function `borrow`](#0x2_object_ref_borrow) +- [Function `borrow_extend`](#0x2_object_ref_borrow_extend) - [Function `borrow_mut`](#0x2_object_ref_borrow_mut) +- [Function `borrow_mut_extend`](#0x2_object_ref_borrow_mut_extend) - [Function `remove`](#0x2_object_ref_remove) +- [Function `remove_extend`](#0x2_object_ref_remove_extend) - [Function `id`](#0x2_object_ref_id) - [Function `owner`](#0x2_object_ref_owner) -- [Function `exist_object`](#0x2_object_ref_exist_object) -- [Function `into_id`](#0x2_object_ref_into_id)
use 0x2::object;
@@ -29,10 +30,9 @@
 
 ObjectRef is a reference of the Object
 It likes ObjectID, but it contains the type information of the object.
-TODO should we support drop?
 
 
-
struct ObjectRef<T> has drop, store, key
+
struct ObjectRef<T> has store, key
 
@@ -53,16 +53,13 @@ TODO should we support drop? - + -## Function `new` +## Function `new_internal` -Get the object reference -This function is protected by private_generics, so it can only be called by the module which defined the T -Note: new ObjectRef need the &mut Object, because the ObjectRef can borrow mutable value from the object -
public fun new<T: key>(object: &mut object::Object<T>): object_ref::ObjectRef<T>
+
public(friend) fun new_internal<T: key>(object: &mut object::Object<T>): object_ref::ObjectRef<T>
 
@@ -71,9 +68,10 @@ Note: new ObjectRef need the &mut Object, because the ObjectRef can borrow mu Implementation -
public fun new<T: key>(object: &mut Object<T>) : ObjectRef<T> {
-    //TODO should we track the reference count?
-    new_internal(object)
+
public(friend) fun new_internal<T: key>(object: &mut Object<T>) : ObjectRef<T> {
+    ObjectRef {
+        id: object::id(object),
+    }
 }
 
@@ -81,13 +79,13 @@ Note: new ObjectRef need the &mut Object, because the ObjectRef can borrow mu - + -## Function `new_internal` +## Function `to_user_owner` -
public(friend) fun new_internal<T: key>(object: &mut object::Object<T>): object_ref::ObjectRef<T>
+
public fun to_user_owner<T: key>(self: object_ref::ObjectRef<T>, owner: address)
 
@@ -96,10 +94,10 @@ Note: new ObjectRef need the &mut Object, because the ObjectRef can borrow mu Implementation -
public(friend) fun new_internal<T: key>(object: &mut Object<T>) : ObjectRef<T> {
-    ObjectRef {
-        id: object::id(object),
-    }
+
public fun to_user_owner<T: key>(self: ObjectRef<T>, owner: address){
+    let ObjectRef{id} = self;
+    let obj = raw_table::borrow_mut_from_global<T>(&id);
+    object::set_owner(obj, owner);
 }
 
@@ -114,7 +112,7 @@ Note: new ObjectRef need the &mut Object, because the ObjectRef can borrow mu Borrow the object value -
public fun borrow<T: key>(self: &object_ref::ObjectRef<T>): &T
+
public fun borrow<T: store, key>(self: &object_ref::ObjectRef<T>): &T
 
@@ -123,7 +121,32 @@ Borrow the object value Implementation -
public fun borrow<T: key>(self: &ObjectRef<T>): &T {
+
public fun borrow<T: key + store>(self: &ObjectRef<T>): &T {
+    let obj = raw_table::borrow_from_global<T>(&self.id);
+    object::internal_borrow(obj)
+}
+
+ + + + + + + +## Function `borrow_extend` + + + +
public fun borrow_extend<T: key>(self: &object_ref::ObjectRef<T>): &T
+
+ + + +
+Implementation + + +
public fun borrow_extend<T: key>(self: &ObjectRef<T>): &T {
     let obj = raw_table::borrow_from_global<T>(&self.id);
     object::internal_borrow(obj)
 }
@@ -140,7 +163,7 @@ Borrow the object value
 Borrow the object mutable value
 
 
-
public fun borrow_mut<T: key>(self: &mut object_ref::ObjectRef<T>): &mut T
+
public fun borrow_mut<T: store, key>(self: &mut object_ref::ObjectRef<T>): &mut T
 
@@ -149,7 +172,7 @@ Borrow the object mutable value Implementation -
public fun borrow_mut<T: key>(self: &mut ObjectRef<T>): &mut T {
+
public fun borrow_mut<T: key + store>(self: &mut ObjectRef<T>): &mut T {
     let obj = raw_table::borrow_mut_from_global<T>(&self.id);
     object::internal_borrow_mut(obj)
 }
@@ -159,14 +182,13 @@ Borrow the object mutable value
 
 
- + -## Function `remove` +## Function `borrow_mut_extend` -Remove the object from the global storage, and return the object value -
public fun remove<T: key>(self: object_ref::ObjectRef<T>): T
+
public fun borrow_mut_extend<T: key>(self: &mut object_ref::ObjectRef<T>): &mut T
 
@@ -175,11 +197,9 @@ Remove the object from the global storage, and return the object value Implementation -
public fun remove<T: key>(self: ObjectRef<T>) : T {
-    let ObjectRef{id} = self;
-    let object = raw_table::remove_from_global(&id);
-    let (_id, _owner, value) = object::unpack_internal(object);
-    value
+
public fun borrow_mut_extend<T: key>(self: &mut ObjectRef<T>): &mut T {
+    let obj = raw_table::borrow_mut_from_global<T>(&self.id);
+    object::internal_borrow_mut(obj)
 }
 
@@ -187,13 +207,14 @@ Remove the object from the global storage, and return the object value - + -## Function `id` +## Function `remove` +Remove the object from the global storage, and return the object value -
public fun id<T>(self: &object_ref::ObjectRef<T>): object::ObjectID
+
public fun remove<T: store, key>(self: object_ref::ObjectRef<T>): T
 
@@ -202,8 +223,11 @@ Remove the object from the global storage, and return the object value Implementation -
public fun id<T>(self: &ObjectRef<T>): ObjectID {
-    self.id
+
public fun remove<T: key + store>(self: ObjectRef<T>) : T {
+    let ObjectRef{id} = self;
+    let object = raw_table::remove_from_global(&id);
+    let (_id, _owner, value) = object::unpack_internal(object);
+    value
 }
 
@@ -211,13 +235,13 @@ Remove the object from the global storage, and return the object value - + -## Function `owner` +## Function `remove_extend` -
public fun owner<T: key>(self: &object_ref::ObjectRef<T>): address
+
public fun remove_extend<T: key>(self: object_ref::ObjectRef<T>): T
 
@@ -226,9 +250,11 @@ Remove the object from the global storage, and return the object value Implementation -
public fun owner<T: key>(self: &ObjectRef<T>): address {
-    let obj = raw_table::borrow_from_global<T>(&self.id);
-    object::owner(obj)
+
public fun remove_extend<T: key>(self: ObjectRef<T>) : T {
+    let ObjectRef{id} = self;
+    let object = raw_table::remove_from_global(&id);
+    let (_id, _owner, value) = object::unpack_internal(object);
+    value
 }
 
@@ -236,14 +262,13 @@ Remove the object from the global storage, and return the object value - + -## Function `exist_object` +## Function `id` -Check if the object is still exist in the global storage -
public fun exist_object<T: key>(self: &object_ref::ObjectRef<T>): bool
+
public fun id<T>(self: &object_ref::ObjectRef<T>): object::ObjectID
 
@@ -252,8 +277,8 @@ Check if the object is still exist in the global storage Implementation -
public fun exist_object<T: key>(self: &ObjectRef<T>): bool {
-    raw_table::contains_global(&self.id)
+
public fun id<T>(self: &ObjectRef<T>): ObjectID {
+    self.id
 }
 
@@ -261,14 +286,13 @@ Check if the object is still exist in the global storage - + -## Function `into_id` +## Function `owner` -Convert the ObjectRef to ObjectID -
public fun into_id<T: key>(self: object_ref::ObjectRef<T>): object::ObjectID
+
public fun owner<T: key>(self: &object_ref::ObjectRef<T>): address
 
@@ -277,9 +301,9 @@ Convert the ObjectRef to ObjectID Implementation -
public fun into_id<T: key>(self: ObjectRef<T>): ObjectID {
-    let ObjectRef {id} = self;
-    id
+
public fun owner<T: key>(self: &ObjectRef<T>): address {
+    let obj = raw_table::borrow_from_global<T>(&self.id);
+    object::owner(obj)
 }
 
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move b/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move index a9a6e15804..f7da976602 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move @@ -52,8 +52,8 @@ module moveos_std::account_storage { resources: type_table::new_with_id(named_table_id(account, NamedTableResource)), modules: table::new_with_id(named_table_id(account, NamedTableModule)), }; - //Should we keep the storage ref? - let _account_storage_ref = context::new_object_with_id(ctx, object_id, account, account_storage); + let obj = object::new(object_id, account_storage); + context::add_object(ctx, obj); } /// check if account storage eixst diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move index 1cfde4e72a..7723feb66b 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move @@ -7,7 +7,6 @@ module moveos_std::context { use std::option::Option; - use moveos_std::type_info; use moveos_std::storage_context::{Self, StorageContext}; use moveos_std::tx_context::{Self, TxContext}; use moveos_std::object::{Self, Object, ObjectID}; @@ -92,28 +91,29 @@ module moveos_std::context { } - // Wrap functions for StorageContext and ObjectRef + // Wrap functions for StorageContext - #[private_generics(T)] /// Borrow Object from object store with object_id - public fun borrow_object(self: &Context, object_id: ObjectID): &Object { + public(friend) fun borrow_object(self: &Context, object_id: ObjectID): &Object { storage_context::borrow(&self.storage_context, object_id) } - #[private_generics(T)] /// Borrow mut Object from object store with object_id - public fun borrow_object_mut(self: &mut Context, object_id: ObjectID): &mut Object { + public(friend) fun borrow_object_mut(self: &mut Context, object_id: ObjectID): &mut Object { storage_context::borrow_mut(&mut self.storage_context, object_id) } - #[private_generics(T)] /// Remove object from object store, and unpack the Object - public fun remove_object(self: &mut Context, object_id: ObjectID): (ObjectID, address, T) { + public(friend) fun remove_object(self: &mut Context, object_id: ObjectID): (ObjectID, address, T) { let obj = storage_context::remove(&mut self.storage_context, object_id); object::unpack_internal(obj) } - public fun exist_object(self: &Context, object_id: ObjectID): bool { + public(friend) fun add_object(self: &mut Context, object: Object) { + storage_context::add(&mut self.storage_context, object); + } + + public(friend) fun exist_object(self: &Context, object_id: ObjectID): bool { storage_context::contains(&self.storage_context, object_id) } @@ -124,20 +124,11 @@ module moveos_std::context { /// Add the Object to the global object storage and return the ObjectRef public fun new_object(self: &mut Context, value: T): ObjectRef { let id = fresh_object_id(self); - let owner = sender(self); - new_object_with_id(self, id, owner, value) - } - - #[private_generics(T)] - /// Create a new Object with owner - /// Add the Object to the global object storage and return the ObjectRef - public fun new_object_with_owner(self: &mut Context, owner: address, value: T): ObjectRef { - let object_id = fresh_object_id(self); - new_object_with_id(self, object_id, owner, value) + new_object_with_id(self, id, value) } - public(friend) fun new_object_with_id(self: &mut Context, id: ObjectID, owner: address, value: T) : ObjectRef { - let obj = object::new(id, owner, value); + public(friend) fun new_object_with_id(self: &mut Context, id: ObjectID, value: T) : ObjectRef { + let obj = object::new(id, value); let obj_ref = object_ref::new_internal(&mut obj); storage_context::add(&mut self.storage_context, obj); obj_ref @@ -146,7 +137,7 @@ module moveos_std::context { #[private_generics(T)] public fun new_singleton_object(self: &mut Context, value: T): ObjectRef { let object_id = object::singleton_object_id(); - new_object_with_id(self, object_id, type_info::account_address(&type_info::type_of()), value) + new_object_with_id(self, object_id, value) } #[test_only] @@ -189,13 +180,14 @@ module moveos_std::context { let ref = new_object(&mut ctx, TestObjectValue{value: 1}); { - let obj_value = object_ref::borrow_mut(&mut ref); + let obj_value = object_ref::borrow_mut_extend(&mut ref); obj_value.value = 2; }; { - let obj_value = object_ref::borrow(&ref); + let obj_value = object_ref::borrow_extend(&ref); assert!(obj_value.value == 2, 1000); }; + object_ref::to_user_owner(ref, sender); drop_test_context(ctx); } } diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move index b643c3433b..9e62a10c31 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move @@ -75,13 +75,13 @@ module moveos_std::event { /// Use EventHandle to generate a unique event handle /// user doesn't need to call this method directly fun new_event_handle(ctx: &mut Context) { - let account_addr = context::sender(ctx); let event_handle_id = derive_event_handle_id(); let event_handle = EventHandle { counter: 0, }; - //TODO should we keep the event_handle_ref? - let _handle_ref = context::new_object_with_id(ctx, event_handle_id, account_addr, event_handle); + //TODO refactor EventHandle with singleton Object. + let event_handle_object = object::new(event_handle_id, event_handle); + context::add_object(ctx, event_handle_object); } public fun ensure_event_handle(ctx: &mut Context) { diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move index 91671cf4cd..0d8455d9e4 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move @@ -12,12 +12,15 @@ module moveos_std::object { use moveos_std::type_info; use moveos_std::bcs; use moveos_std::address; + friend moveos_std::context; friend moveos_std::account_storage; friend moveos_std::storage_context; friend moveos_std::event; friend moveos_std::object_ref; friend moveos_std::raw_table; + + const CODE_OWNER_ADDRESS: address = @0x0; /// Box style object /// The object can not be copied, droped and stored. It only can be consumed by StorageContext API. @@ -54,8 +57,13 @@ module moveos_std::object { ) } + public fun code_owner_address(): address { + CODE_OWNER_ADDRESS + } + /// Create a new object, the object is owned by `owner` - public(friend) fun new(id: ObjectID, owner: address, value: T): Object { + public(friend) fun new(id: ObjectID, value: T): Object { + let owner = CODE_OWNER_ADDRESS; Object{id, value, owner} } @@ -79,6 +87,10 @@ module moveos_std::object { &mut self.value } + public(friend) fun set_owner(self: &mut Object, owner: address) { + self.owner = owner; + } + #[private_generics(T)] /// Transfer object to recipient public fun transfer(self: &mut Object, recipient: address) { @@ -118,7 +130,7 @@ module moveos_std::object { count: object_count, }; let object_id = address_to_object_id(moveos_std::tx_context::fresh_address(&mut tx_context)); - let obj = new(object_id, sender_addr, object); + let obj = new(object_id, object); let borrow_object = borrow_mut(&mut obj); assert!(borrow_object.count == object_count, 1001); diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move index 973b15e344..61079e2a0f 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move @@ -10,40 +10,57 @@ module moveos_std::object_ref { /// ObjectRef is a reference of the Object /// It likes ObjectID, but it contains the type information of the object. - /// TODO should we support drop? - struct ObjectRef has key, store, drop { + struct ObjectRef has key, store { id: ObjectID, } - #[private_generics(T)] - /// Get the object reference - /// This function is protected by private_generics, so it can only be called by the module which defined the T - /// Note: new ObjectRef need the &mut Object, because the ObjectRef can borrow mutable value from the object - public fun new(object: &mut Object) : ObjectRef { - //TODO should we track the reference count? - new_internal(object) - } - public(friend) fun new_internal(object: &mut Object) : ObjectRef { ObjectRef { id: object::id(object), } } + #[private_generics(T)] + public fun to_user_owner(self: ObjectRef, owner: address){ + let ObjectRef{id} = self; + let obj = raw_table::borrow_mut_from_global(&id); + object::set_owner(obj, owner); + } + /// Borrow the object value - public fun borrow(self: &ObjectRef): &T { + public fun borrow(self: &ObjectRef): &T { + let obj = raw_table::borrow_from_global(&self.id); + object::internal_borrow(obj) + } + + #[private_generics(T)] + public fun borrow_extend(self: &ObjectRef): &T { let obj = raw_table::borrow_from_global(&self.id); object::internal_borrow(obj) } /// Borrow the object mutable value - public fun borrow_mut(self: &mut ObjectRef): &mut T { + public fun borrow_mut(self: &mut ObjectRef): &mut T { let obj = raw_table::borrow_mut_from_global(&self.id); object::internal_borrow_mut(obj) } + #[private_generics(T)] + public fun borrow_mut_extend(self: &mut ObjectRef): &mut T { + let obj = raw_table::borrow_mut_from_global(&self.id); + object::internal_borrow_mut(obj) + } + /// Remove the object from the global storage, and return the object value - public fun remove(self: ObjectRef) : T { + public fun remove(self: ObjectRef) : T { + let ObjectRef{id} = self; + let object = raw_table::remove_from_global(&id); + let (_id, _owner, value) = object::unpack_internal(object); + value + } + + #[private_generics(T)] + public fun remove_extend(self: ObjectRef) : T { let ObjectRef{id} = self; let object = raw_table::remove_from_global(&id); let (_id, _owner, value) = object::unpack_internal(object); @@ -59,14 +76,4 @@ module moveos_std::object_ref { object::owner(obj) } - /// Check if the object is still exist in the global storage - public fun exist_object(self: &ObjectRef): bool { - raw_table::contains_global(&self.id) - } - - /// Convert the ObjectRef to ObjectID - public fun into_id(self: ObjectRef): ObjectID { - let ObjectRef {id} = self; - id - } } diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/storage_context.move b/moveos/moveos-stdlib/moveos-stdlib/sources/storage_context.move index 7d5b58b883..23d09fb0e7 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/storage_context.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/storage_context.move @@ -92,12 +92,12 @@ module moveos_std::storage_context { let ctx = moveos_std::tx_context::new_test_context(sender); let os = new(&mut ctx); let object_id = object::address_to_object_id(moveos_std::tx_context::fresh_address(&mut ctx)); - let object = object::new(object_id, sender, TestObject { f: 1 }); + let object = object::new(object_id, TestObject { f: 1 }); add(&mut os, object); assert!(contains(&os, object_id), 1000); let object_id2 = object::address_to_object_id(moveos_std::tx_context::fresh_address(&mut ctx)); - let object2 = object::new(object_id2, sender, TestObject2 { f: 1 }); + let object2 = object::new(object_id2, TestObject2 { f: 1 }); // The object_id2 is not in the object storage assert!(!contains(&os, object_id2), 1001); @@ -123,7 +123,7 @@ module moveos_std::storage_context { let ctx = moveos_std::tx_context::new_test_context(sender_addr); let os = new(&mut ctx); let object_id = object::address_to_object_id(moveos_std::tx_context::fresh_address(&mut ctx)); - let object = object::new(object_id, sender_addr, TestObject { f: 1 }); + let object = object::new(object_id, TestObject { f: 1 }); let _obj_ref = borrow(&os, object_id); drop_object_storage(os); @@ -138,7 +138,7 @@ module moveos_std::storage_context { let ctx = moveos_std::tx_context::new_test_context(sender_addr); let os = new(&mut ctx); let object_id = object::address_to_object_id(moveos_std::tx_context::fresh_address(&mut ctx)); - let object = object::new(object_id, sender_addr, TestObject { f: 1 }); + let object = object::new(object_id, TestObject { f: 1 }); add(&mut os, object); let obj_rem1 = remove(&mut os, object_id); let obj_rem2 = remove(&mut os, object_id); @@ -156,7 +156,7 @@ module moveos_std::storage_context { let ctx = moveos_std::tx_context::new_test_context(sender_addr); let os = new(&mut ctx); let object_id = object::address_to_object_id(moveos_std::tx_context::fresh_address(&mut ctx)); - let object = object::new(object_id, sender_addr, TestObject { f: 1 }); + let object = object::new(object_id, TestObject { f: 1 }); let obj_rem = remove(&mut os, object_id); drop_object_storage(os); diff --git a/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs b/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs index c89fdc7ef2..48e254502e 100644 --- a/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs +++ b/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs @@ -144,11 +144,13 @@ fn native_sort_and_verify_modules_inner( } module_names.push(module.self_id().name().to_owned().into_string()); } - Err(_) => { + Err(e) => { + //TODO provide a flag to control whether to print debug log. + log::info!("module {} verification error: {:?}", module.self_id(), e); return Ok(NativeResult::err( cost, moveos_types::move_std::error::invalid_argument(E_MODULE_VERIFICATION_ERROR), - )) + )); } } } diff --git a/moveos/moveos-types/src/state.rs b/moveos/moveos-types/src/state.rs index d0c2eba1d0..a3c5b56adb 100644 --- a/moveos/moveos-types/src/state.rs +++ b/moveos/moveos-types/src/state.rs @@ -9,6 +9,7 @@ use anyhow::{bail, ensure, Result}; use move_core_types::{ account_address::AccountAddress, effects::Op, + ident_str, identifier::{IdentStr, Identifier}, language_storage::{StructTag, TypeTag}, resolver::MoveResolver, @@ -48,6 +49,10 @@ pub trait MoveStructType: MoveType { const MODULE_NAME: &'static IdentStr; const STRUCT_NAME: &'static IdentStr; + fn module_address() -> AccountAddress { + Self::ADDRESS + } + fn module_identifier() -> Identifier { Self::MODULE_NAME.to_owned() } @@ -288,6 +293,20 @@ where } } +/// A placeholder struct for unknown Move Struct +/// Sometimes we need a generic struct type, but we don't know the struct type +pub struct PlaceholderStruct; + +impl MoveStructType for PlaceholderStruct { + const ADDRESS: AccountAddress = AccountAddress::ZERO; + const MODULE_NAME: &'static IdentStr = ident_str!("placeholder"); + const STRUCT_NAME: &'static IdentStr = ident_str!("PlaceholderStruct"); + + fn type_params() -> Vec { + panic!("PlaceholderStruct should not be used as a type") + } +} + /// Move State is a trait that is used to represent the state of a Move Resource in Rust /// It is like the `MoveResource` in move_core_types pub trait MoveStructState: MoveState + MoveStructType + DeserializeOwned + Serialize { diff --git a/moveos/moveos-verifier/src/metadata.rs b/moveos/moveos-verifier/src/metadata.rs index 97c0617da3..7d9d0a3386 100644 --- a/moveos/moveos-verifier/src/metadata.rs +++ b/moveos/moveos-verifier/src/metadata.rs @@ -487,6 +487,7 @@ pub fn is_allowed_input_struct(name: String) -> bool { | "0x1::ascii::String" | "0x2::object::ObjectID" | "0x2::context::Context" + | "0x2::object_ref::ObjectRef" ) } diff --git a/moveos/moveos-verifier/src/verifier.rs b/moveos/moveos-verifier/src/verifier.rs index 7c825516ab..9907222f51 100644 --- a/moveos/moveos-verifier/src/verifier.rs +++ b/moveos/moveos-verifier/src/verifier.rs @@ -12,6 +12,7 @@ use move_binary_format::file_format::{ FunctionInstantiation, FunctionInstantiationIndex, Signature, SignatureToken, StructHandleIndex, Visibility, }; +use move_binary_format::IndexKind; use move_binary_format::{access::ModuleAccess, CompiledModule}; use move_core_types::identifier::Identifier; use move_core_types::language_storage::ModuleId; @@ -181,10 +182,11 @@ pub fn verify_entry_function_at_publish(module: &CompiledModule) -> VMResult VMResult( func: &LoadedFunctionInstantiation, session: &Session, -) -> PartialVMResult +) -> PartialVMResult<()> where S: DataStore + TransactionCache, { @@ -207,14 +209,14 @@ where ); } - for ty in &func.parameters { + for (idx, ty) in func.parameters.iter().enumerate() { if !check_transaction_input_type(ty, session) { return Err(PartialVMError::new(StatusCode::TYPE_MISMATCH) - .with_message("parameter type is not allowed".to_owned())); + .with_message(format!("The type of the {} paramter is not allowed", idx))); } } - Ok(true) + Ok(()) } fn check_transaction_input_type_at_publish( @@ -256,13 +258,9 @@ fn is_allowed_reference_types_at_publish( module_bin_view: &BinaryIndexedView, ) -> bool { match bt { - SignatureToken::Struct(sid) => { + SignatureToken::Struct(sid) | SignatureToken::StructInstantiation(sid, _) => { let struct_full_name = struct_full_name_from_sid(sid, module_bin_view); - if is_allowed_input_struct(struct_full_name) { - return true; - } - - false + is_allowed_input_struct(struct_full_name) } _ => false, } @@ -332,15 +330,19 @@ where S: DataStore + TransactionCache, { match bt { - Type::Struct(sid) => { - if let Some(st) = session.get_struct_type(*sid) { + Type::Struct(sid) | Type::StructInstantiation(sid, _) => { + let st_option = session.get_struct_type(*sid); + debug_assert!( + st_option.is_some(), + "Can not find by struct handle index:{:?}", + sid + ); + if let Some(st) = st_option { let full_name = format!("{}::{}", st.module.short_str_lossless(), st.name); - if is_allowed_input_struct(full_name) { - return true; - } + is_allowed_input_struct(full_name) + } else { + false } - - false } _ => false, } diff --git a/moveos/moveos/src/vm/moveos_vm.rs b/moveos/moveos/src/vm/moveos_vm.rs index 5e5511959b..aea2e9e6a0 100644 --- a/moveos/moveos/src/vm/moveos_vm.rs +++ b/moveos/moveos/src/vm/moveos_vm.rs @@ -1,10 +1,7 @@ // Copyright (c) RoochNetwork // SPDX-License-Identifier: Apache-2.0 -use super::{ - data_cache::{into_change_set, MoveosDataCache}, - tx_argument_resolver::TxArgumentResolver, -}; +use super::data_cache::{into_change_set, MoveosDataCache}; use move_binary_format::{ compatibility::Compatibility, errors::{Location, PartialVMError, VMError, VMResult}, @@ -106,13 +103,13 @@ impl MoveOSVM { /// It is used to execute a transaction, every transaction should be executed in a new session. /// Every session has a TxContext, if the transaction have multiple actions, the TxContext is shared. pub struct MoveOSSession<'r, 'l, S, G> { - vm: &'l MoveVM, - remote: &'r S, - session: Session<'r, 'l, MoveosDataCache<'r, 'l, S>>, - ctx: Context, - table_data: Arc>, - gas_meter: G, - read_only: bool, + pub(crate) vm: &'l MoveVM, + pub(crate) remote: &'r S, + pub(crate) session: Session<'r, 'l, MoveosDataCache<'r, 'l, S>>, + pub(crate) ctx: Context, + pub(crate) table_data: Arc>, + pub(crate) gas_meter: G, + pub(crate) read_only: bool, } impl<'r, 'l, S, G> MoveOSSession<'r, 'l, S, G> @@ -187,10 +184,7 @@ where .load_script(call.code.as_slice(), call.ty_args.clone())?; moveos_verifier::verifier::verify_entry_function(&loaded_function, &self.session) .map_err(|e| e.finish(Location::Undefined))?; - let _resolved_args = self - .ctx - .resolve_argument(&self.session, &loaded_function, call.args.clone()) - .map_err(|e| e.finish(Location::Undefined))?; + let _resolved_args = self.resolve_argument(&loaded_function, call.args.clone())?; Ok(VerifiedMoveAction::Script { call }) } MoveAction::Function(call) => { @@ -201,10 +195,7 @@ where )?; moveos_verifier::verifier::verify_entry_function(&loaded_function, &self.session) .map_err(|e| e.finish(Location::Undefined))?; - let _resolved_args = self - .ctx - .resolve_argument(&self.session, &loaded_function, call.args.clone()) - .map_err(|e| e.finish(Location::Undefined))?; + let _resolved_args = self.resolve_argument(&loaded_function, call.args.clone())?; Ok(VerifiedMoveAction::Function { call }) } MoveAction::ModuleBundle(module_bundle) => { @@ -243,11 +234,8 @@ where .session .load_script(call.code.as_slice(), call.ty_args.clone())?; - let resolved_args = self - .ctx - .resolve_argument(&self.session, &loaded_function, call.args) - .map_err(|e| e.finish(Location::Undefined))?; - + let resolved_args = self.resolve_argument(&loaded_function, call.args)?; + self.load_argument(&loaded_function, &resolved_args); self.session .execute_script(call.code, call.ty_args, resolved_args, &mut self.gas_meter) .map(|ret| { @@ -265,11 +253,8 @@ where call.ty_args.as_slice(), )?; - let resolved_args = self - .ctx - .resolve_argument(&self.session, &loaded_function, call.args) - .map_err(|e| e.finish(Location::Undefined))?; - + let resolved_args = self.resolve_argument(&loaded_function, call.args)?; + self.load_argument(&loaded_function, &resolved_args); self.session .execute_entry_function( &call.function_id.module_id, @@ -371,13 +356,8 @@ where &call.function_id.function_name, call.ty_args.as_slice(), )?; - let resolved_args = self - .ctx - .resolve_argument(&self.session, &loaded_function, call.args) - .map_err(|e: move_binary_format::errors::PartialVMError| { - e.finish(Location::Undefined) - })?; - + let resolved_args = self.resolve_argument(&loaded_function, call.args)?; + self.load_argument(&loaded_function, &resolved_args); let return_values = self.session.execute_function_bypass_visibility( &call.function_id.module_id, &call.function_id.function_name, diff --git a/moveos/moveos/src/vm/tx_argument_resolver.rs b/moveos/moveos/src/vm/tx_argument_resolver.rs index a9439a4dd1..b197cbb694 100644 --- a/moveos/moveos/src/vm/tx_argument_resolver.rs +++ b/moveos/moveos/src/vm/tx_argument_resolver.rs @@ -1,43 +1,40 @@ // Copyright (c) RoochNetwork // SPDX-License-Identifier: Apache-2.0 -use anyhow::Result; -use move_binary_format::errors::PartialVMError; -use move_core_types::value::MoveValue; +use super::moveos_vm::MoveOSSession; +use crate::gas::SwitchableGasMeter; +use move_binary_format::errors::{Location, PartialVMError, VMResult}; +use move_core_types::{ + language_storage::{StructTag, TypeTag}, + value::MoveValue, + vm_status::StatusCode, +}; use move_vm_runtime::session::{LoadedFunctionInstantiation, Session}; use move_vm_types::{ data_store::{DataStore, TransactionCache}, loaded_data::runtime_types::{StructType, Type}, }; -use moveos_types::{moveos_std::context::Context, state::MoveStructType}; +use moveos_types::{ + moveos_std::{context::Context, object::ObjectID, object_ref::ObjectRef}, + state::{MoveStructType, PlaceholderStruct}, + state_resolver::MoveOSResolver, +}; use std::sync::Arc; -/// Transaction Argument Resolver will implemented by the Move Extension -/// to auto fill transaction argument or do type conversion. -pub trait TxArgumentResolver { - fn resolve_argument( - &self, - session: &Session, - func: &LoadedFunctionInstantiation, - args: Vec>, - ) -> Result>, PartialVMError> - where - S: DataStore + TransactionCache; -} - -impl TxArgumentResolver for Context { - fn resolve_argument( +impl<'r, 'l, S, G> MoveOSSession<'r, 'l, S, G> +where + S: MoveOSResolver, + G: SwitchableGasMeter, +{ + pub fn resolve_argument( &self, - session: &Session, func: &LoadedFunctionInstantiation, mut args: Vec>, - ) -> Result>, PartialVMError> - where - S: DataStore + TransactionCache, - { + ) -> VMResult>> { + //fill in signer and context func.parameters.iter().enumerate().for_each(|(i, t)| { if is_signer(t) { - let signer = MoveValue::Signer(self.tx_context.sender()); + let signer = MoveValue::Signer(self.ctx.tx_context.sender()); args.insert( i, signer @@ -45,48 +42,111 @@ impl TxArgumentResolver for Context { .expect("serialize signer should success"), ); } - - if as_struct(session, t) - .map(|t| is_storage_context(&t)) + let struct_opt = as_struct_no_panic(&self.session, t); + if struct_opt + .as_ref() + .map(|t| is_storage_context(t)) .unwrap_or(false) { - args.insert(i, self.to_bytes()); + args.insert(i, self.ctx.to_bytes()); } }); + + //check object id + if func.parameters.len() != args.len() { + return Err( + PartialVMError::new(StatusCode::NUMBER_OF_ARGUMENTS_MISMATCH) + .with_message(format!( + "Invalid argument length, expect:{}, got:{}", + func.parameters.len(), + args.len() + )) + .finish(Location::Undefined), + ); + } + for (paramter, arg) in func.parameters.iter().zip(args.iter()) { + let type_tag_opt = get_type_tag(&self.session, paramter)?; + if let Some(t) = type_tag_opt { + if let Some(object_type) = get_object_type(&t) { + let object_id = ObjectID::from_bytes(arg).map_err(|e| { + PartialVMError::new(StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT) + .with_message(format!("Invalid object id: {:?}", e)) + .finish(Location::Undefined) + })?; + let state = self + .remote + .resolve_object_state(&object_id) + .map_err(|e| { + PartialVMError::new(StatusCode::STORAGE_ERROR) + .with_message(format!("Failed to resolve object state: {:?}", e)) + .finish(Location::Undefined) + })? + .ok_or_else(|| { + PartialVMError::new(StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT) + .with_message(format!("Object not found: {:?}", object_id)) + .finish(Location::Undefined) + })?; + let object = state.as_raw_object().map_err(|e| { + PartialVMError::new(StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT) + .with_message(format!("Invalid object state: {:?}", e)) + .finish(Location::Undefined) + })?; + if let TypeTag::Struct(s) = object_type { + if s.as_ref() != &object.value.struct_tag { + return Err(PartialVMError::new( + StatusCode::TYPE_MISMATCH, + ) + .with_message(format!( + "Invalid object type, object type in argument:{:?}, object type in store:{:?}", + s, object.value.struct_tag + )).finish(Location::Undefined)); + } + } else { + return Err(PartialVMError::new(StatusCode::TYPE_MISMATCH) + .with_message(format!( + "Object type should be struct, got:{:?}", + object_type + )) + .finish(Location::Undefined)); + } + } + } + } Ok(args) } + + pub fn load_argument(&mut self, _func: &LoadedFunctionInstantiation, _args: &[Vec]) { + //TODO load the object argument to the session + // If the argument is `ObjectRef`, we need to change the Object to code owner object. + // We need to refactor the raw table, migrate the TableData to StorageContext. + } } fn is_signer(t: &Type) -> bool { matches!(t, Type::Signer) || matches!(t, Type::Reference(r) if matches!(**r, Type::Signer)) } -fn as_struct(session: &Session, t: &Type) -> Option> +pub fn as_struct_no_panic(session: &Session, t: &Type) -> Option> where T: DataStore + TransactionCache, { match t { - Type::Struct(s) | Type::StructInstantiation(s, _) => match session.get_struct_type(*s) { - Some(t) => Some(t), - None => { - panic!("Can not find type for struct: {:?}", s) - } - }, - Type::Reference(r) => as_struct(session, r), - Type::MutableReference(r) => as_struct(session, r), + Type::Struct(s) | Type::StructInstantiation(s, _) => session.get_struct_type(*s), + Type::Reference(r) => as_struct_no_panic(session, r), + Type::MutableReference(r) => as_struct_no_panic(session, r), _ => None, } } -pub fn as_struct_no_panic(session: &Session, t: &Type) -> Option> +pub fn get_type_tag(session: &Session, t: &Type) -> VMResult> where T: DataStore + TransactionCache, { match t { - Type::Struct(s) | Type::StructInstantiation(s, _) => session.get_struct_type(*s), - Type::Reference(r) => as_struct_no_panic(session, r), - Type::MutableReference(r) => as_struct_no_panic(session, r), - _ => None, + Type::Struct(_) | Type::StructInstantiation(_, _) => Ok(Some(session.get_type_tag(t)?)), + Type::Reference(r) => get_type_tag(session, r), + Type::MutableReference(r) => get_type_tag(session, r), + _ => Ok(None), } } @@ -95,3 +155,29 @@ pub fn is_storage_context(t: &StructType) -> bool { && t.module.name() == Context::module_identifier().as_ident_str() && t.name == Context::struct_identifier() } + +pub fn is_object(t: &TypeTag) -> bool { + match t { + TypeTag::Struct(s) => is_object_struct(s), + _ => false, + } +} + +pub fn is_object_struct(t: &StructTag) -> bool { + t.address == ObjectRef::::module_address() + && t.module == ObjectRef::::module_identifier() + && t.name == ObjectRef::::struct_identifier() +} + +pub fn get_object_type(type_tag: &TypeTag) -> Option { + match type_tag { + TypeTag::Struct(s) => { + if is_object_struct(s) { + s.type_params.get(0).cloned() + } else { + None + } + } + _ => None, + } +} From e48186755a752c825fcf5e26c7c4f71e6cd8ee3c Mon Sep 17 00:00:00 2001 From: jolestar Date: Tue, 24 Oct 2023 15:54:46 +0800 Subject: [PATCH 02/18] [CLI] verify modules when publish at client side. --- crates/rooch-rpc-client/src/lib.rs | 26 +++++++++++++++++++ crates/rooch-types/src/error.rs | 7 +++-- .../src/commands/move_cli/commands/publish.rs | 4 ++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/crates/rooch-rpc-client/src/lib.rs b/crates/rooch-rpc-client/src/lib.rs index 2f3ffefefb..8e831fc7f7 100644 --- a/crates/rooch-rpc-client/src/lib.rs +++ b/crates/rooch-rpc-client/src/lib.rs @@ -5,6 +5,11 @@ use anyhow::Result; use eth_client::EthRpcClient; use jsonrpsee::core::client::ClientT; use jsonrpsee::http_client::{HttpClient, HttpClientBuilder}; +use move_core_types::language_storage::ModuleId; +use move_core_types::resolver::ModuleResolver; +use moveos_types::access_path::AccessPath; +use moveos_types::moveos_std::move_module::MoveModule; +use moveos_types::state::State; use moveos_types::{ function_return_value::FunctionResult, module_binding::MoveFunctionCaller, moveos_std::tx_context::TxContext, transaction::FunctionCall, @@ -103,3 +108,24 @@ impl MoveFunctionCaller for Client { function_result.try_into() } } + +impl ModuleResolver for &Client { + type Error = anyhow::Error; + fn get_module(&self, id: &ModuleId) -> Result>, Self::Error> { + futures::executor::block_on(async { + let mut states = self + .rooch + .get_states(AccessPath::module(*id.address(), id.name().to_owned())) + .await?; + states + .pop() + .flatten() + .map(|state_view| { + let state = State::from(state_view); + let module = state.as_move_state::()?; + Ok(module.byte_codes) + }) + .transpose() + }) + } +} diff --git a/crates/rooch-types/src/error.rs b/crates/rooch-types/src/error.rs index a3b44b817c..7a45c08836 100644 --- a/crates/rooch-types/src/error.rs +++ b/crates/rooch-types/src/error.rs @@ -1,16 +1,16 @@ // Copyright (c) RoochNetwork // SPDX-License-Identifier: Apache-2.0 +use move_binary_format::errors::VMError; use move_core_types::vm_status::VMStatus; use moveos_types::genesis_info::GenesisInfo; -use serde::{Deserialize, Serialize}; use std::io; use thiserror::Error; pub type RoochResult = Result; /// Custom error type for Rooch. -#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, Error, Hash)] +#[derive(Eq, PartialEq, Clone, Debug, Error)] pub enum RoochError { /// config #[error("Unable to find config {0}, have you run `rooch init`?")] @@ -120,6 +120,9 @@ pub enum RoochError { #[error("Invalid sequencer or proposer or relayer key pair")] InvalidSequencerOrProposerOrRelayerKeyPair, + + #[error("VM error: {0}")] + VMError(VMError), } impl From for RoochError { diff --git a/crates/rooch/src/commands/move_cli/commands/publish.rs b/crates/rooch/src/commands/move_cli/commands/publish.rs index 2801148ff3..3c22be4db3 100644 --- a/crates/rooch/src/commands/move_cli/commands/publish.rs +++ b/crates/rooch/src/commands/move_cli/commands/publish.rs @@ -9,6 +9,7 @@ use move_bytecode_utils::dependency_graph::DependencyGraph; use move_bytecode_utils::Modules; use move_cli::Move; use move_core_types::{identifier::Identifier, language_storage::ModuleId}; +use moveos_verifier::verifier; use rooch_key::key_derive::verify_password; use rooch_rpc_api::jsonrpc_types::ExecuteTransactionResponseView; use rooch_types::transaction::rooch::RoochTransaction; @@ -101,7 +102,7 @@ impl CommandAction for Publish { // Initialize bundles vector and sort modules by dependency order let mut bundles: Vec> = vec![]; let sorted_modules = sort_by_dependency_order(modules.iter_modules())?; - + let resolver = context.get_client().await?; // Serialize and collect module binaries into bundles for module in sorted_modules { let module_address = module.self_id().address().to_owned(); @@ -112,6 +113,7 @@ impl CommandAction for Publish { pkg_address.clone(), ))); }; + verifier::verify_module(&module, &resolver).map_err(|e| RoochError::VMError(e))?; let mut binary: Vec = vec![]; module.serialize(&mut binary)?; bundles.push(binary); From 61c5fb7b4d6de8f9cf475ffc6c4deaefea31db9e Mon Sep 17 00:00:00 2001 From: jolestar Date: Tue, 24 Oct 2023 15:55:21 +0800 Subject: [PATCH 03/18] [Example] refactor simple_blog example via new ObjectRef API --- crates/rooch-types/src/error.rs | 9 +-- .../src/commands/move_cli/commands/publish.rs | 2 +- examples/simple_blog/sources/article.move | 55 +++++++------------ examples/simple_blog/sources/blog.move | 13 +++-- 4 files changed, 31 insertions(+), 48 deletions(-) diff --git a/crates/rooch-types/src/error.rs b/crates/rooch-types/src/error.rs index 7a45c08836..fe3884ad73 100644 --- a/crates/rooch-types/src/error.rs +++ b/crates/rooch-types/src/error.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 use move_binary_format::errors::VMError; -use move_core_types::vm_status::VMStatus; use moveos_types::genesis_info::GenesisInfo; use std::io; use thiserror::Error; @@ -37,8 +36,6 @@ pub enum RoochError { UnableToReadFile(String, String), #[error("Error: {0}")] UnexpectedError(String), - #[error("Error: {0}")] - UnexpectedVMStatusError(String), #[error("Simulation failed with status: {0}")] SimulationError(String), @@ -143,9 +140,9 @@ impl From for RoochError { } } -impl From for RoochError { - fn from(e: VMStatus) -> Self { - RoochError::UnexpectedVMStatusError(e.to_string()) +impl From for RoochError { + fn from(e: VMError) -> Self { + RoochError::VMError(e) } } diff --git a/crates/rooch/src/commands/move_cli/commands/publish.rs b/crates/rooch/src/commands/move_cli/commands/publish.rs index 3c22be4db3..88eb5e644f 100644 --- a/crates/rooch/src/commands/move_cli/commands/publish.rs +++ b/crates/rooch/src/commands/move_cli/commands/publish.rs @@ -113,7 +113,7 @@ impl CommandAction for Publish { pkg_address.clone(), ))); }; - verifier::verify_module(&module, &resolver).map_err(|e| RoochError::VMError(e))?; + verifier::verify_module(&module, &resolver)?; let mut binary: Vec = vec![]; module.serialize(&mut binary)?; bundles.push(binary); diff --git a/examples/simple_blog/sources/article.move b/examples/simple_blog/sources/article.move index 4938506a54..43c0d51333 100644 --- a/examples/simple_blog/sources/article.move +++ b/examples/simple_blog/sources/article.move @@ -7,14 +7,14 @@ module simple_blog::article { use std::signer; use std::string::String; use moveos_std::event; - use moveos_std::object::{Self, Object, ObjectID}; - use moveos_std::object_ref; + use moveos_std::object::{ObjectID}; + use moveos_std::object_ref::{Self, ObjectRef}; use moveos_std::context::{Self, Context}; const ErrorDataTooLong: u64 = 1; const ErrorNotOwnerAccount: u64 = 2; - struct Article has key { + struct Article has key,store { version: u64, title: String, body: String, @@ -51,9 +51,8 @@ module simple_blog::article { body, }; let owner_addr = signer::address_of(owner); - let article_ref = context::new_object_with_owner( + let article_ref = context::new_object( ctx, - owner_addr, article, ); let id = object_ref::id(&article_ref); @@ -62,27 +61,22 @@ module simple_blog::article { id, }; event::emit(ctx, article_created_event); + object_ref::to_user_owner(article_ref, owner_addr); id } /// Update article public fun update_article( ctx: &mut Context, - owner: &signer, - id: ObjectID, + article_obj: &mut ObjectRef
, new_title: String, new_body: String, ) { assert!(std::string::length(&new_title) <= 200, error::invalid_argument(ErrorDataTooLong)); assert!(std::string::length(&new_body) <= 2000, error::invalid_argument(ErrorDataTooLong)); - let article_obj = context::borrow_object_mut
(ctx, id); - let owner_address = signer::address_of(owner); - - // only article owner can update the article - assert!(object::owner(article_obj) == owner_address, error::permission_denied(ErrorNotOwnerAccount)); - - let article = object::borrow_mut(article_obj); + let id = object_ref::id(article_obj); + let article = object_ref::borrow_mut(article_obj); article.version = article.version + 1; article.title = new_title; article.body = new_body; @@ -97,16 +91,16 @@ module simple_blog::article { /// Delete article public fun delete_article( ctx: &mut Context, - owner: &signer, - id: ObjectID, + article_obj: ObjectRef
, ) { - - let owner_address = signer::address_of(owner); - let (id, owner, article) = context::remove_object
(ctx, id); + //let owner_address = signer::address_of(owner); + let id = object_ref::id(&article_obj); + let article = object_ref::remove(article_obj); + //let (id, owner, article) = context::remove_object
(ctx, id); // only article owner can delete the article - assert!(owner == owner_address, error::permission_denied(ErrorNotOwnerAccount)); + //assert!(owner == owner_address, error::permission_denied(ErrorNotOwnerAccount)); let article_deleted_event = ArticleDeletedEvent { id, @@ -126,29 +120,20 @@ module simple_blog::article { /// Read function of article - /// get article object by id - public fun get_article(ctx: &Context, article_id: ObjectID): &Object
{ - context::borrow_object
(ctx, article_id) - } - - /// get article id - public fun id(article_obj: &Object
): ObjectID { - object::id(article_obj) - } /// get article version - public fun version(article_obj: &Object
): u64 { - object::borrow(article_obj).version + public fun version(article_obj: &ObjectRef
): u64 { + object_ref::borrow(article_obj).version } /// get article title - public fun title(article_obj: &Object
): String { - object::borrow(article_obj).title + public fun title(article_obj: &ObjectRef
): String { + object_ref::borrow(article_obj).title } /// get article body - public fun body(article_obj: &Object
): String { - object::borrow(article_obj).body + public fun body(article_obj: &ObjectRef
): String { + object_ref::borrow(article_obj).body } } diff --git a/examples/simple_blog/sources/blog.move b/examples/simple_blog/sources/blog.move index 86f2722fd3..6e49957eb8 100644 --- a/examples/simple_blog/sources/blog.move +++ b/examples/simple_blog/sources/blog.move @@ -7,9 +7,10 @@ module simple_blog::blog { use std::string::{Self,String}; use std::vector; use moveos_std::object::ObjectID; + use moveos_std::object_ref::{Self, ObjectRef}; use moveos_std::context::Context; use moveos_std::account_storage; - use simple_blog::article; + use simple_blog::article::{Self, Article}; const ErrorDataTooLong: u64 = 1; const ErrorNotFound: u64 = 2; @@ -86,20 +87,20 @@ module simple_blog::blog { public entry fun update_article( ctx: &mut Context, - owner: signer, - id: ObjectID, + article_obj: &mut ObjectRef
, new_title: String, new_body: String, ) { - article::update_article(ctx, &owner, id, new_title, new_body); + article::update_article(ctx, article_obj, new_title, new_body); } public entry fun delete_article( ctx: &mut Context, owner: signer, - id: ObjectID, + article_obj: ObjectRef
, ) { - article::delete_article(ctx, &owner, id); + let id = object_ref::id(&article_obj); + article::delete_article(ctx, article_obj); delete_article_from_myblog(ctx, &owner, id); } } From 05e9994cc7912119d59863ce4c94643c3d922707 Mon Sep 17 00:00:00 2001 From: jolestar Date: Wed, 25 Oct 2023 17:01:46 +0800 Subject: [PATCH 04/18] [MoveosStd] Add native function as_ref_inner and as_mut_ref_inner --- .../tests/cases/object/basic.move | 6 +- .../tests/cases/table/basic.move | 2 +- crates/rooch-framework/doc/coin_store.md | 15 +- .../rooch-framework/sources/coin_store.move | 15 +- .../src/natives/gas_parameter/mod.rs | 1 + .../src/natives/gas_parameter/object.rs | 10 ++ crates/rooch-framework/src/natives/mod.rs | 2 + examples/simple_blog/sources/article.move | 3 +- .../moveos-stdlib/doc/account_storage.md | 10 +- .../moveos-stdlib/doc/context.md | 80 ++-------- .../moveos-stdlib/moveos-stdlib/doc/event.md | 3 +- .../moveos-stdlib/moveos-stdlib/doc/object.md | 104 ++----------- .../moveos-stdlib/doc/object_ref.md | 129 ++++++++++++++-- .../sources/account_storage.move | 14 +- .../moveos-stdlib/sources/context.move | 38 ++--- .../moveos-stdlib/sources/event.move | 18 ++- .../moveos-stdlib/sources/object.move | 36 ++--- .../moveos-stdlib/sources/object_ref.move | 42 ++++- moveos/moveos-stdlib/src/natives/mod.rs | 6 + .../src/natives/moveos_stdlib/mod.rs | 1 + .../src/natives/moveos_stdlib/object.rs | 145 ++++++++++++++++++ moveos/moveos/src/vm/tx_argument_resolver.rs | 12 +- 22 files changed, 430 insertions(+), 262 deletions(-) create mode 100644 crates/rooch-framework/src/natives/gas_parameter/object.rs create mode 100644 moveos/moveos-stdlib/src/natives/moveos_stdlib/object.rs diff --git a/crates/rooch-framework-tests/tests/cases/object/basic.move b/crates/rooch-framework-tests/tests/cases/object/basic.move index 904ac49c27..5ac6041fa2 100644 --- a/crates/rooch-framework-tests/tests/cases/object/basic.move +++ b/crates/rooch-framework-tests/tests/cases/object/basic.move @@ -17,9 +17,8 @@ module test::m { // if the tx hash change, need to figure out why. assert!(x"7852c5dcbd87e82102dba0db36d44b5a9fb0006b3e828c0b5f0832f70a8ff6ee" == tx_hash, 1000); let obj_ref = context::new_object(ctx, S { v: 1}); - let sender = context::sender(ctx); debug::print(&obj_ref); - object_ref::to_user_owner(obj_ref, sender); + object_ref::to_external(obj_ref); } public entry fun move_s_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef) { @@ -32,8 +31,7 @@ module test::m { public entry fun mint_cup(ctx: &mut Context) { let obj_ref = context::new_object(ctx, Cup { v: 2 }); debug::print(&obj_ref); - let sender = context::sender(ctx); - object_ref::to_user_owner(obj_ref, sender); + object_ref::to_external(obj_ref); } public entry fun move_cup_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef>) { diff --git a/crates/rooch-framework-tests/tests/cases/table/basic.move b/crates/rooch-framework-tests/tests/cases/table/basic.move index b500aa1b91..2001203ffd 100644 --- a/crates/rooch-framework-tests/tests/cases/table/basic.move +++ b/crates/rooch-framework-tests/tests/cases/table/basic.move @@ -33,7 +33,7 @@ module test::m { public fun save_to_object_storage(ctx: &mut Context, kv: KVStore) : ObjectID { let object_ref = context::new_object(ctx, kv); let object_id = object_ref::id(&object_ref); - object_ref::to_user_owner(object_ref, context::sender(ctx)); + object_ref::to_external(object_ref); object_id } } diff --git a/crates/rooch-framework/doc/coin_store.md b/crates/rooch-framework/doc/coin_store.md index 46eb7844ec..476da8a317 100644 --- a/crates/rooch-framework/doc/coin_store.md +++ b/crates/rooch-framework/doc/coin_store.md @@ -358,7 +358,7 @@ This function is for he CoinType module to extend, Only the CoinType module can freeze or unfreeze a CoinStore by the coin store id -
public fun freeze_coin_store_extend<CoinType: key>(_ctx: &mut context::Context, _coin_store_id: object::ObjectID, _frozen: bool)
+
public fun freeze_coin_store_extend<CoinType: key>(ctx: &mut context::Context, coin_store_id: object::ObjectID, frozen: bool)
 
@@ -368,14 +368,13 @@ Only the CoinType module can freeze or unfreeze a CoinStore by the
public fun freeze_coin_store_extend<CoinType: key>(
-    _ctx: &mut Context,
-    _coin_store_id: ObjectID,
-    _frozen: bool,
+    ctx: &mut Context,
+    coin_store_id: ObjectID,
+    frozen: bool,
 ) {
-    //TODO how to provide freeze coin store via coin store id
-    // assert!(context::exist_object(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound));
-    // let coin_store_object = context::borrow_object_mut<CoinStore>(ctx, coin_store_id);
-    // object::borrow_mut(coin_store_object).frozen = frozen;
+    assert!(context::exist_object<CoinStore>(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound));
+    let coin_store_object = context::borrow_object_mut<CoinStore>(ctx, coin_store_id);
+    object_ref::borrow_mut(coin_store_object).frozen = frozen;
 }
 
diff --git a/crates/rooch-framework/sources/coin_store.move b/crates/rooch-framework/sources/coin_store.move index 46c3c13104..afd8c6188d 100644 --- a/crates/rooch-framework/sources/coin_store.move +++ b/crates/rooch-framework/sources/coin_store.move @@ -8,7 +8,7 @@ module rooch_framework::coin_store { use moveos_std::object::{ObjectID}; use moveos_std::context::{Self, Context}; use moveos_std::type_info; - use moveos_std::object_ref::{ObjectRef}; + use moveos_std::object_ref::{Self, ObjectRef}; use rooch_framework::coin::{Self, Coin}; friend rooch_framework::account_coin_store; @@ -96,14 +96,13 @@ module rooch_framework::coin_store { /// This function is for he `CoinType` module to extend, /// Only the `CoinType` module can freeze or unfreeze a CoinStore by the coin store id public fun freeze_coin_store_extend( - _ctx: &mut Context, - _coin_store_id: ObjectID, - _frozen: bool, + ctx: &mut Context, + coin_store_id: ObjectID, + frozen: bool, ) { - //TODO how to provide freeze coin store via coin store id - // assert!(context::exist_object(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound)); - // let coin_store_object = context::borrow_object_mut(ctx, coin_store_id); - // object::borrow_mut(coin_store_object).frozen = frozen; + assert!(context::exist_object(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound)); + let coin_store_object = context::borrow_object_mut(ctx, coin_store_id); + object_ref::borrow_mut(coin_store_object).frozen = frozen; } // Internal functions diff --git a/crates/rooch-framework/src/natives/gas_parameter/mod.rs b/crates/rooch-framework/src/natives/gas_parameter/mod.rs index 78cae4ea69..939d0d2b9f 100644 --- a/crates/rooch-framework/src/natives/gas_parameter/mod.rs +++ b/crates/rooch-framework/src/natives/gas_parameter/mod.rs @@ -14,6 +14,7 @@ mod move_module; pub mod move_std; pub mod native; pub mod nursery; +mod object; mod rlp; mod schnorr; mod signer; diff --git a/crates/rooch-framework/src/natives/gas_parameter/object.rs b/crates/rooch-framework/src/natives/gas_parameter/object.rs new file mode 100644 index 0000000000..56c49c9346 --- /dev/null +++ b/crates/rooch-framework/src/natives/gas_parameter/object.rs @@ -0,0 +1,10 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +use crate::natives::gas_parameter::native::MUL; +use moveos_stdlib::natives::moveos_stdlib::object::GasParameters; + +crate::natives::gas_parameter::native::define_gas_parameters_for_natives!(GasParameters, "object", [ + [.as_ref_inner.base, "as_ref_inner.base", (5 + 1) * MUL], + [.as_mut_ref_inner.base, "as_mut_ref_inner.base", (5 + 1) * MUL], +]); diff --git a/crates/rooch-framework/src/natives/mod.rs b/crates/rooch-framework/src/natives/mod.rs index 488f73f8e6..6cc05dfae3 100644 --- a/crates/rooch-framework/src/natives/mod.rs +++ b/crates/rooch-framework/src/natives/mod.rs @@ -77,6 +77,7 @@ impl FromOnChainGasSchedule for MoveOSGasParameters { test_helper: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule).unwrap(), signer: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule).unwrap(), move_module: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule).unwrap(), + object: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule).unwrap(), }) } } @@ -94,6 +95,7 @@ impl InitialGasSchedule for MoveOSGasParameters { test_helper: InitialGasSchedule::initial(), signer: InitialGasSchedule::initial(), move_module: InitialGasSchedule::initial(), + object: InitialGasSchedule::initial(), } } } diff --git a/examples/simple_blog/sources/article.move b/examples/simple_blog/sources/article.move index 43c0d51333..a3061109ef 100644 --- a/examples/simple_blog/sources/article.move +++ b/examples/simple_blog/sources/article.move @@ -61,7 +61,8 @@ module simple_blog::article { id, }; event::emit(ctx, article_created_event); - object_ref::to_user_owner(article_ref, owner_addr); + object_ref::transfer(&mut article_ref, owner_addr); + object_ref::to_external(article_ref); id } diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md b/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md index d8216984e5..f599982b15 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md @@ -31,6 +31,7 @@ It is used to store the account's resources and modules use 0x2::context; use 0x2::move_module; use 0x2::object; +use 0x2::object_ref; use 0x2::table; use 0x2::tx_context; use 0x2::type_table; @@ -193,13 +194,14 @@ Create a new account storage space
public fun create_account_storage(ctx: &mut Context, account: address) {
     let object_id = object::address_to_object_id(account);
-    assert!(!context::exist_object(ctx, object_id), ErrorAccountAlreadyExists);
+    assert!(!context::exist_object<AccountStorage>(ctx, object_id), ErrorAccountAlreadyExists);
     let account_storage = AccountStorage {
         resources: type_table::new_with_id(named_table_id(account, NamedTableResource)),
         modules: table::new_with_id(named_table_id(account, NamedTableModule)),
     };
-    let obj = object::new(object_id, account_storage);
-    context::add_object(ctx, obj);
+    let obj = context::new_object_with_id(ctx, object_id, account_storage);
+    object_ref::transfer_extend(&mut obj, account);
+    object_ref::to_external(obj);
 }
 
@@ -225,7 +227,7 @@ check if account storage eixst
public fun exist_account_storage(ctx: &Context, account: address): bool {
     let object_id = object::address_to_object_id(account);
-    context::exist_object(ctx, object_id)
+    context::exist_object<AccountStorage>(ctx, object_id)
 }
 
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md index d56af20306..49c91b9187 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md @@ -23,8 +23,6 @@ and let developers customize the storage - [Function `tx_result`](#0x2_context_tx_result) - [Function `borrow_object`](#0x2_context_borrow_object) - [Function `borrow_object_mut`](#0x2_context_borrow_object_mut) -- [Function `remove_object`](#0x2_context_remove_object) -- [Function `add_object`](#0x2_context_add_object) - [Function `exist_object`](#0x2_context_exist_object) - [Function `new_object`](#0x2_context_new_object) - [Function `new_object_with_id`](#0x2_context_new_object_with_id) @@ -385,7 +383,7 @@ Get a value from the context map Borrow Object from object store with object_id -
public(friend) fun borrow_object<T: key>(self: &context::Context, object_id: object::ObjectID): &object::Object<T>
+
public fun borrow_object<T: key>(self: &context::Context, object_id: object::ObjectID): &object_ref::ObjectRef<T>
 
@@ -394,8 +392,9 @@ Borrow Object from object store with object_id Implementation -
public(friend) fun borrow_object<T: key>(self: &Context, object_id: ObjectID): &Object<T> {
-    storage_context::borrow<T>(&self.storage_context, object_id)
+
public fun borrow_object<T: key>(self: &Context, object_id: ObjectID): &ObjectRef<T> {
+    let object_entity = storage_context::borrow<T>(&self.storage_context, object_id);
+    object_ref::as_ref(object_entity)
 }
 
@@ -410,7 +409,7 @@ Borrow Object from object store with object_id Borrow mut Object from object store with object_id -
public(friend) fun borrow_object_mut<T: key>(self: &mut context::Context, object_id: object::ObjectID): &mut object::Object<T>
+
public fun borrow_object_mut<T: key>(self: &mut context::Context, object_id: object::ObjectID): &mut object_ref::ObjectRef<T>
 
@@ -419,58 +418,9 @@ Borrow mut Object from object store with object_id Implementation -
public(friend) fun borrow_object_mut<T: key>(self: &mut Context, object_id: ObjectID): &mut Object<T> {
-    storage_context::borrow_mut<T>(&mut self.storage_context, object_id)
-}
-
- - - - - - - -## Function `remove_object` - -Remove object from object store, and unpack the Object - - -
public(friend) fun remove_object<T: key>(self: &mut context::Context, object_id: object::ObjectID): (object::ObjectID, address, T)
-
- - - -
-Implementation - - -
public(friend) fun remove_object<T: key>(self: &mut Context, object_id: ObjectID): (ObjectID, address, T) {
-    let obj = storage_context::remove<T>(&mut self.storage_context, object_id);
-    object::unpack_internal(obj)
-}
-
- - - -
- - - -## Function `add_object` - - - -
public(friend) fun add_object<T: key>(self: &mut context::Context, object: object::Object<T>)
-
- - - -
-Implementation - - -
public(friend) fun add_object<T: key>(self: &mut Context, object: Object<T>) {
-    storage_context::add(&mut self.storage_context, object);
+
public fun borrow_object_mut<T: key>(self: &mut Context, object_id: ObjectID): &mut ObjectRef<T> {
+    let object_entity = storage_context::borrow_mut<T>(&mut self.storage_context, object_id);
+    object_ref::as_mut_ref(object_entity)
 }
 
@@ -484,7 +434,7 @@ Remove object from object store, and unpack the Object -
public(friend) fun exist_object(self: &context::Context, object_id: object::ObjectID): bool
+
public fun exist_object<T: key>(self: &context::Context, object_id: object::ObjectID): bool
 
@@ -493,8 +443,9 @@ Remove object from object store, and unpack the Object Implementation -
public(friend) fun exist_object(self: &Context, object_id: ObjectID): bool {
+
public fun exist_object<T: key>(self: &Context, object_id: ObjectID): bool {
     storage_context::contains(&self.storage_context, object_id)
+    //TODO check the object type
 }
 
@@ -506,7 +457,7 @@ Remove object from object store, and unpack the Object ## Function `new_object` -Create a new Object, the owner is the sender +Create a new Object, the default owner is the sender Add the Object to the global object storage and return the ObjectRef @@ -545,9 +496,10 @@ Add the Object to the global object storage and return the ObjectRef
public(friend) fun new_object_with_id<T: key>(self: &mut Context, id: ObjectID, value: T) : ObjectRef<T> {
-    let obj = object::new(id, value);
-    let obj_ref = object_ref::new_internal(&mut obj);
-    storage_context::add(&mut self.storage_context, obj);
+    let obj_entity = object::new(id, value);
+    object::set_owner(&mut obj_entity, sender(self));
+    let obj_ref = object_ref::new_internal(&mut obj_entity);
+    storage_context::add(&mut self.storage_context, obj_entity);
     obj_ref
 }
 
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/event.md b/moveos/moveos-stdlib/moveos-stdlib/doc/event.md index 3b44907403..f4b6885ed7 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/event.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/event.md @@ -19,6 +19,7 @@ events emitted to a handle and emit events to the event store. use 0x2::bcs; use 0x2::context; use 0x2::object; +use 0x2::object_ref; use 0x2::type_info;
@@ -33,7 +34,7 @@ A handle for an event such that: 2. Storage can use this handle to prove the total number of events that happened in the past. -
struct EventHandle has store, key
+
struct EventHandle has key
 
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md index 0658f145cf..1138480974 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md @@ -18,15 +18,12 @@ The differents with the Object in [Sui](https://github.com/MystenLabs/sui/blob/5 - [Function `code_owner_address`](#0x2_object_code_owner_address) - [Function `new`](#0x2_object_new) - [Function `borrow`](#0x2_object_borrow) -- [Function `internal_borrow`](#0x2_object_internal_borrow) - [Function `borrow_mut`](#0x2_object_borrow_mut) -- [Function `internal_borrow_mut`](#0x2_object_internal_borrow_mut) - [Function `set_owner`](#0x2_object_set_owner) -- [Function `transfer`](#0x2_object_transfer) +- [Function `set_external`](#0x2_object_set_external) - [Function `id`](#0x2_object_id) - [Function `owner`](#0x2_object_owner) - [Function `unpack`](#0x2_object_unpack) -- [Function `unpack_internal`](#0x2_object_unpack_internal)
use 0x1::hash;
@@ -41,6 +38,7 @@ The differents with the Object in [Sui](https://github.com/MystenLabs/sui/blob/5
 
 ## Struct `Object`
 
+TODO rename to ObjectEntity
 Box style object
 The object can not be copied, droped and stored. It only can be consumed by StorageContext API.
 
@@ -71,7 +69,7 @@ The object can not be copied, droped and stored. It only can be consumed by Stor
 value: T
 
 
- + Whether the object is external
@@ -233,31 +231,7 @@ Create a new object, the object is owned by owner -
public fun borrow<T>(self: &object::Object<T>): &T
-
- - - -
-Implementation - - -
public fun borrow<T>(self: &Object<T>): &T {
-    &self.value
-}
-
- - - -
- - - -## Function `internal_borrow` - - - -
public(friend) fun internal_borrow<T>(self: &object::Object<T>): &T
+
public(friend) fun borrow<T>(self: &object::Object<T>): &T
 
@@ -266,7 +240,7 @@ Create a new object, the object is owned by owner Implementation -
public(friend) fun internal_borrow<T>(self: &Object<T>): &T {
+
public(friend) fun borrow<T>(self: &Object<T>): &T {
     &self.value
 }
 
@@ -279,34 +253,9 @@ Create a new object, the object is owned by owner ## Function `borrow_mut` -Borrow the mutable object value - - -
public fun borrow_mut<T>(self: &mut object::Object<T>): &mut T
-
- - - -
-Implementation - -
public fun borrow_mut<T>(self: &mut Object<T>): &mut T {
-    &mut self.value
-}
-
- - - -
- - -## Function `internal_borrow_mut` - - - -
public(friend) fun internal_borrow_mut<T>(self: &mut object::Object<T>): &mut T
+
public(friend) fun borrow_mut<T>(self: &mut object::Object<T>): &mut T
 
@@ -315,7 +264,7 @@ Borrow the mutable object value Implementation -
public(friend) fun internal_borrow_mut<T>(self: &mut Object<T>): &mut T {
+
public(friend) fun borrow_mut<T>(self: &mut Object<T>): &mut T {
     &mut self.value
 }
 
@@ -348,14 +297,13 @@ Borrow the mutable object value
- + -## Function `transfer` +## Function `set_external` -Transfer object to recipient -
public fun transfer<T: key>(self: &mut object::Object<T>, recipient: address)
+
public(friend) fun set_external<T>(_self: &mut object::Object<T>, _external: bool)
 
@@ -364,8 +312,8 @@ Transfer object to recipient Implementation -
public fun transfer<T: key>(self: &mut Object<T>, recipient: address) {
-    self.owner = recipient;
+
public(friend) fun set_external<T>(_self: &mut Object<T>, _external: bool) {
+    //self.external = external;
 }
 
@@ -428,31 +376,7 @@ Transfer object to recipient Unpack the object, return the id, owner, and value -
public fun unpack<T>(self: object::Object<T>): (object::ObjectID, address, T)
-
- - - -
-Implementation - - -
public fun unpack<T>(self: Object<T>): (ObjectID, address, T) {
-    unpack_internal(self)
-}
-
- - - -
- - - -## Function `unpack_internal` - - - -
public(friend) fun unpack_internal<T>(self: object::Object<T>): (object::ObjectID, address, T)
+
public(friend) fun unpack<T>(self: object::Object<T>): (object::ObjectID, address, T)
 
@@ -461,7 +385,7 @@ Unpack the object, return the id, owner, and value Implementation -
public(friend) fun unpack_internal<T>(self: Object<T>): (ObjectID, address, T) {
+
public(friend) fun unpack<T>(self: Object<T>): (ObjectID, address, T) {
     let Object{id, owner, value} = self;
     (id, owner, value)
 }
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md
index cc3a5b484a..3278457aa6 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md
+++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md
@@ -7,13 +7,17 @@
 
 -  [Resource `ObjectRef`](#0x2_object_ref_ObjectRef)
 -  [Function `new_internal`](#0x2_object_ref_new_internal)
--  [Function `to_user_owner`](#0x2_object_ref_to_user_owner)
+-  [Function `as_ref`](#0x2_object_ref_as_ref)
+-  [Function `as_mut_ref`](#0x2_object_ref_as_mut_ref)
+-  [Function `to_external`](#0x2_object_ref_to_external)
 -  [Function `borrow`](#0x2_object_ref_borrow)
 -  [Function `borrow_extend`](#0x2_object_ref_borrow_extend)
 -  [Function `borrow_mut`](#0x2_object_ref_borrow_mut)
 -  [Function `borrow_mut_extend`](#0x2_object_ref_borrow_mut_extend)
 -  [Function `remove`](#0x2_object_ref_remove)
 -  [Function `remove_extend`](#0x2_object_ref_remove_extend)
+-  [Function `transfer`](#0x2_object_ref_transfer)
+-  [Function `transfer_extend`](#0x2_object_ref_transfer_extend)
 -  [Function `id`](#0x2_object_ref_id)
 -  [Function `owner`](#0x2_object_ref_owner)
 
@@ -28,6 +32,7 @@
 
 ## Resource `ObjectRef`
 
+TODO rename to Object
 ObjectRef is a reference of the Object
 It likes ObjectID, but it contains the type information of the object.
 
@@ -79,13 +84,13 @@ It likes ObjectID, but it contains the type information of the object.
 
 
 
-
+
 
-## Function `to_user_owner`
+## Function `as_ref`
 
 
 
-
public fun to_user_owner<T: key>(self: object_ref::ObjectRef<T>, owner: address)
+
public(friend) fun as_ref<T: key>(object: &object::Object<T>): &object_ref::ObjectRef<T>
 
@@ -94,10 +99,60 @@ It likes ObjectID, but it contains the type information of the object. Implementation -
public fun to_user_owner<T: key>(self: ObjectRef<T>, owner: address){
+
public(friend) fun as_ref<T: key>(object: &Object<T>) : &ObjectRef<T>{
+    as_ref_inner<ObjectRef<T>>(object::id(object))
+}
+
+ + + + + + + +## Function `as_mut_ref` + + + +
public(friend) fun as_mut_ref<T: key>(object: &mut object::Object<T>): &mut object_ref::ObjectRef<T>
+
+ + + +
+Implementation + + +
public(friend) fun as_mut_ref<T: key>(object: &mut Object<T>) : &mut ObjectRef<T>{
+    as_mut_ref_inner<ObjectRef<T>>(object::id(object))
+}
+
+ + + +
+ + + +## Function `to_external` + +Drop the ObjectRef, and make the object to be a external object. +The external object can be used as transaction argument + + +
public fun to_external<T: key>(self: object_ref::ObjectRef<T>)
+
+ + + +
+Implementation + + +
public fun to_external<T: key>(self: ObjectRef<T>){
     let ObjectRef{id} = self;
     let obj = raw_table::borrow_mut_from_global<T>(&id);
-    object::set_owner(obj, owner);
+    object::set_external(obj, true);
 }
 
@@ -123,7 +178,7 @@ Borrow the object value
public fun borrow<T: key + store>(self: &ObjectRef<T>): &T {
     let obj = raw_table::borrow_from_global<T>(&self.id);
-    object::internal_borrow(obj)
+    object::borrow(obj)
 }
 
@@ -148,7 +203,7 @@ Borrow the object value
public fun borrow_extend<T: key>(self: &ObjectRef<T>): &T {
     let obj = raw_table::borrow_from_global<T>(&self.id);
-    object::internal_borrow(obj)
+    object::borrow(obj)
 }
 
@@ -174,7 +229,7 @@ Borrow the object mutable value
public fun borrow_mut<T: key + store>(self: &mut ObjectRef<T>): &mut T {
     let obj = raw_table::borrow_mut_from_global<T>(&self.id);
-    object::internal_borrow_mut(obj)
+    object::borrow_mut(obj)
 }
 
@@ -199,7 +254,7 @@ Borrow the object mutable value
public fun borrow_mut_extend<T: key>(self: &mut ObjectRef<T>): &mut T {
     let obj = raw_table::borrow_mut_from_global<T>(&self.id);
-    object::internal_borrow_mut(obj)
+    object::borrow_mut(obj)
 }
 
@@ -226,7 +281,7 @@ Remove the object from the global storage, and return the object value
public fun remove<T: key + store>(self: ObjectRef<T>) : T {
     let ObjectRef{id} = self;
     let object = raw_table::remove_from_global(&id);
-    let (_id, _owner, value) = object::unpack_internal(object);
+    let (_id, _owner, value) = object::unpack(object);
     value
 }
 
@@ -253,13 +308,63 @@ Remove the object from the global storage, and return the object value
public fun remove_extend<T: key>(self: ObjectRef<T>) : T {
     let ObjectRef{id} = self;
     let object = raw_table::remove_from_global(&id);
-    let (_id, _owner, value) = object::unpack_internal(object);
+    let (_id, _owner, value) = object::unpack(object);
     value
 }
 
+
+ + + +## Function `transfer` + + + +
public fun transfer<T: store, key>(self: &mut object_ref::ObjectRef<T>, new_owner: address)
+
+ + + +
+Implementation + + +
public fun transfer<T: key + store>(self: &mut ObjectRef<T>, new_owner: address) {
+    let obj = raw_table::borrow_mut_from_global<T>(&self.id);
+    object::set_owner(obj, new_owner);
+}
+
+ + + +
+ + + +## Function `transfer_extend` + + + +
public fun transfer_extend<T: key>(self: &mut object_ref::ObjectRef<T>, new_owner: address)
+
+ + + +
+Implementation + + +
public fun transfer_extend<T: key>(self: &mut ObjectRef<T>, new_owner: address) {
+    let obj = raw_table::borrow_mut_from_global<T>(&self.id);
+    object::set_owner(obj, new_owner);
+}
+
+ + +
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move b/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move index f7da976602..01a858dbcb 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move @@ -12,6 +12,7 @@ module moveos_std::account_storage { use moveos_std::type_table::{Self, TypeTable}; use moveos_std::table::{Self, Table}; use moveos_std::object::{Self, ObjectID}; + use moveos_std::object_ref; use moveos_std::context::{Self, Context}; use moveos_std::tx_context; use moveos_std::move_module::{Self, MoveModule}; @@ -47,19 +48,20 @@ module moveos_std::account_storage { /// Create a new account storage space public fun create_account_storage(ctx: &mut Context, account: address) { let object_id = object::address_to_object_id(account); - assert!(!context::exist_object(ctx, object_id), ErrorAccountAlreadyExists); + assert!(!context::exist_object(ctx, object_id), ErrorAccountAlreadyExists); let account_storage = AccountStorage { resources: type_table::new_with_id(named_table_id(account, NamedTableResource)), modules: table::new_with_id(named_table_id(account, NamedTableModule)), }; - let obj = object::new(object_id, account_storage); - context::add_object(ctx, obj); + let obj = context::new_object_with_id(ctx, object_id, account_storage); + object_ref::transfer_extend(&mut obj, account); + object_ref::to_external(obj); } /// check if account storage eixst public fun exist_account_storage(ctx: &Context, account: address): bool { let object_id = object::address_to_object_id(account); - context::exist_object(ctx, object_id) + context::exist_object(ctx, object_id) } public fun ensure_account_storage(ctx: &mut Context, account: address) { @@ -73,13 +75,13 @@ module moveos_std::account_storage { fun borrow_account_storage(ctx: &Context, account: address): &AccountStorage{ let object_id = object::address_to_object_id(account); let object = context::borrow_object(ctx, object_id); - object::borrow(object) + object_ref::borrow_extend(object) } fun borrow_account_storage_mut(ctx: &mut Context, account: address): &mut AccountStorage{ let object_id = object::address_to_object_id(account); let object = context::borrow_object_mut(ctx, object_id); - object::borrow_mut(object) + object_ref::borrow_mut_extend(object) } /// Borrow a resource from the AccountStorage diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move index 7723feb66b..b6b4a5eded 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move @@ -9,7 +9,7 @@ module moveos_std::context { use std::option::Option; use moveos_std::storage_context::{Self, StorageContext}; use moveos_std::tx_context::{Self, TxContext}; - use moveos_std::object::{Self, Object, ObjectID}; + use moveos_std::object::{Self, ObjectID}; use moveos_std::object_ref::{Self, ObjectRef}; use moveos_std::tx_meta::{TxMeta}; use moveos_std::tx_result::{TxResult}; @@ -93,34 +93,29 @@ module moveos_std::context { // Wrap functions for StorageContext + #[private_generics(T)] /// Borrow Object from object store with object_id - public(friend) fun borrow_object(self: &Context, object_id: ObjectID): &Object { - storage_context::borrow(&self.storage_context, object_id) + public fun borrow_object(self: &Context, object_id: ObjectID): &ObjectRef { + let object_entity = storage_context::borrow(&self.storage_context, object_id); + object_ref::as_ref(object_entity) } + #[private_generics(T)] /// Borrow mut Object from object store with object_id - public(friend) fun borrow_object_mut(self: &mut Context, object_id: ObjectID): &mut Object { - storage_context::borrow_mut(&mut self.storage_context, object_id) - } - - /// Remove object from object store, and unpack the Object - public(friend) fun remove_object(self: &mut Context, object_id: ObjectID): (ObjectID, address, T) { - let obj = storage_context::remove(&mut self.storage_context, object_id); - object::unpack_internal(obj) - } - - public(friend) fun add_object(self: &mut Context, object: Object) { - storage_context::add(&mut self.storage_context, object); + public fun borrow_object_mut(self: &mut Context, object_id: ObjectID): &mut ObjectRef { + let object_entity = storage_context::borrow_mut(&mut self.storage_context, object_id); + object_ref::as_mut_ref(object_entity) } - public(friend) fun exist_object(self: &Context, object_id: ObjectID): bool { + public fun exist_object(self: &Context, object_id: ObjectID): bool { storage_context::contains(&self.storage_context, object_id) + //TODO check the object type } // Wrap functions for Object #[private_generics(T)] - /// Create a new Object, the owner is the `sender` + /// Create a new Object, the default owner is the `sender` /// Add the Object to the global object storage and return the ObjectRef public fun new_object(self: &mut Context, value: T): ObjectRef { let id = fresh_object_id(self); @@ -128,9 +123,10 @@ module moveos_std::context { } public(friend) fun new_object_with_id(self: &mut Context, id: ObjectID, value: T) : ObjectRef { - let obj = object::new(id, value); - let obj_ref = object_ref::new_internal(&mut obj); - storage_context::add(&mut self.storage_context, obj); + let obj_entity = object::new(id, value); + object::set_owner(&mut obj_entity, sender(self)); + let obj_ref = object_ref::new_internal(&mut obj_entity); + storage_context::add(&mut self.storage_context, obj_entity); obj_ref } @@ -187,7 +183,7 @@ module moveos_std::context { let obj_value = object_ref::borrow_extend(&ref); assert!(obj_value.value == 2, 1000); }; - object_ref::to_user_owner(ref, sender); + object_ref::to_external(ref); drop_test_context(ctx); } } diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move index 9e62a10c31..2daff4cbd6 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move @@ -10,6 +10,7 @@ module moveos_std::event { use moveos_std::bcs; use moveos_std::context::{Self, Context}; use moveos_std::object::{Self, ObjectID}; + use moveos_std::object_ref; use moveos_std::type_info; #[test_only] @@ -20,7 +21,7 @@ module moveos_std::event { /// A handle for an event such that: /// 1. Other modules can emit events to this handle. /// 2. Storage can use this handle to prove the total number of events that happened in the past. - struct EventHandle has key, store { + struct EventHandle has key { /// Total number of events emitted to this event stream. counter: u64, } @@ -34,28 +35,28 @@ module moveos_std::event { fun exists_event_handle(ctx: &Context): bool { let event_handle_id = derive_event_handle_id(); - context::exist_object(ctx, event_handle_id) + context::exist_object(ctx, event_handle_id) } /// Borrow a event handle from the object storage fun borrow_event_handle(ctx: &Context): &EventHandle { let event_handle_id = derive_event_handle_id(); let object = context::borrow_object(ctx, event_handle_id); - object::borrow(object) + object_ref::borrow_extend(object) } /// Borrow a mut event handle from the object storage fun borrow_event_handle_mut(ctx: &mut Context): &mut EventHandle { let event_handle_id = derive_event_handle_id(); let object = context::borrow_object_mut(ctx, event_handle_id); - object::borrow_mut(object) + object_ref::borrow_mut_extend(object) } /// Get event handle owner fun get_event_handle_owner(ctx: &Context): address { let event_handle_id = derive_event_handle_id(); let object = context::borrow_object(ctx, event_handle_id); - object::owner(object) + object_ref::owner(object) } /// Method to get event handle Metadata @@ -80,8 +81,11 @@ module moveos_std::event { counter: 0, }; //TODO refactor EventHandle with singleton Object. - let event_handle_object = object::new(event_handle_id, event_handle); - context::add_object(ctx, event_handle_object); + let obj = context::new_object_with_id(ctx, event_handle_id, event_handle); + let type_info = type_info::type_of(); + let owner = type_info::account_address(&type_info); + object_ref::transfer_extend(&mut obj, owner); + object_ref::to_external(obj); } public fun ensure_event_handle(ctx: &mut Context) { diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move index 0d8455d9e4..f7cc79cdd5 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move @@ -21,7 +21,8 @@ module moveos_std::object { friend moveos_std::raw_table; const CODE_OWNER_ADDRESS: address = @0x0; - + + ///TODO rename to ObjectEntity /// Box style object /// The object can not be copied, droped and stored. It only can be consumed by StorageContext API. struct Object { @@ -29,6 +30,8 @@ module moveos_std::object { id: ObjectID, // The owner of the object owner: address, + /// Whether the object is external + //external: bool, // The value of the object // The value must be the last field value: T, @@ -67,23 +70,11 @@ module moveos_std::object { Object{id, value, owner} } - #[private_generics(T)] - // Borrow the object value - public fun borrow(self: &Object): &T { + public(friend) fun borrow(self: &Object): &T { &self.value } - public(friend) fun internal_borrow(self: &Object): &T { - &self.value - } - - #[private_generics(T)] - /// Borrow the mutable object value - public fun borrow_mut(self: &mut Object): &mut T { - &mut self.value - } - - public(friend) fun internal_borrow_mut(self: &mut Object): &mut T { + public(friend) fun borrow_mut(self: &mut Object): &mut T { &mut self.value } @@ -91,10 +82,8 @@ module moveos_std::object { self.owner = owner; } - #[private_generics(T)] - /// Transfer object to recipient - public fun transfer(self: &mut Object, recipient: address) { - self.owner = recipient; + public(friend) fun set_external(_self: &mut Object, _external: bool) { + //self.external = external; } public fun id(self: &Object): ObjectID { @@ -105,13 +94,8 @@ module moveos_std::object { self.owner } - #[private_generics(T)] /// Unpack the object, return the id, owner, and value - public fun unpack(self: Object): (ObjectID, address, T) { - unpack_internal(self) - } - - public(friend) fun unpack_internal(self: Object): (ObjectID, address, T) { + public(friend) fun unpack(self: Object): (ObjectID, address, T) { let Object{id, owner, value} = self; (id, owner, value) } @@ -135,7 +119,7 @@ module moveos_std::object { let borrow_object = borrow_mut(&mut obj); assert!(borrow_object.count == object_count, 1001); - transfer(&mut obj, @0x10); + set_owner(&mut obj, @0x10); let obj_owner = owner(&obj); assert!(obj_owner != sender_addr, 1002); diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move index 61079e2a0f..57738f5792 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move @@ -8,6 +8,7 @@ module moveos_std::object_ref { friend moveos_std::context; + ///TODO rename to Object /// ObjectRef is a reference of the Object /// It likes ObjectID, but it contains the type information of the object. struct ObjectRef has key, store { @@ -20,42 +21,56 @@ module moveos_std::object_ref { } } + public(friend) fun as_ref(object: &Object) : &ObjectRef{ + as_ref_inner>(object::id(object)) + } + public(friend) fun as_mut_ref(object: &mut Object) : &mut ObjectRef{ + as_mut_ref_inner>(object::id(object)) + } + + /// Convert the ObjectID to &T or &mut T + /// The caller must ensure the T only has one `ObjectID` field, such as `ObjectRef` or `Table`, or `TypeTable`. + native fun as_ref_inner(object_id: ObjectID): &T; + native fun as_mut_ref_inner(object_id: ObjectID): &mut T; + #[private_generics(T)] - public fun to_user_owner(self: ObjectRef, owner: address){ + /// Drop the ObjectRef, and make the object to be a external object. + /// The external object can be used as transaction argument + public fun to_external(self: ObjectRef){ let ObjectRef{id} = self; let obj = raw_table::borrow_mut_from_global(&id); - object::set_owner(obj, owner); + object::set_external(obj, true); } /// Borrow the object value public fun borrow(self: &ObjectRef): &T { let obj = raw_table::borrow_from_global(&self.id); - object::internal_borrow(obj) + object::borrow(obj) } #[private_generics(T)] public fun borrow_extend(self: &ObjectRef): &T { let obj = raw_table::borrow_from_global(&self.id); - object::internal_borrow(obj) + object::borrow(obj) } /// Borrow the object mutable value public fun borrow_mut(self: &mut ObjectRef): &mut T { let obj = raw_table::borrow_mut_from_global(&self.id); - object::internal_borrow_mut(obj) + object::borrow_mut(obj) } #[private_generics(T)] public fun borrow_mut_extend(self: &mut ObjectRef): &mut T { let obj = raw_table::borrow_mut_from_global(&self.id); - object::internal_borrow_mut(obj) + object::borrow_mut(obj) } /// Remove the object from the global storage, and return the object value public fun remove(self: ObjectRef) : T { let ObjectRef{id} = self; let object = raw_table::remove_from_global(&id); - let (_id, _owner, value) = object::unpack_internal(object); + let (_id, _owner, value) = object::unpack(object); value } @@ -63,10 +78,21 @@ module moveos_std::object_ref { public fun remove_extend(self: ObjectRef) : T { let ObjectRef{id} = self; let object = raw_table::remove_from_global(&id); - let (_id, _owner, value) = object::unpack_internal(object); + let (_id, _owner, value) = object::unpack(object); value } + public fun transfer(self: &mut ObjectRef, new_owner: address) { + let obj = raw_table::borrow_mut_from_global(&self.id); + object::set_owner(obj, new_owner); + } + + #[private_generics(T)] + public fun transfer_extend(self: &mut ObjectRef, new_owner: address) { + let obj = raw_table::borrow_mut_from_global(&self.id); + object::set_owner(obj, new_owner); + } + public fun id(self: &ObjectRef): ObjectID { self.id } diff --git a/moveos/moveos-stdlib/src/natives/mod.rs b/moveos/moveos-stdlib/src/natives/mod.rs index ce31691036..9db11dad8a 100644 --- a/moveos/moveos-stdlib/src/natives/mod.rs +++ b/moveos/moveos-stdlib/src/natives/mod.rs @@ -21,6 +21,7 @@ pub struct GasParameters { pub test_helper: moveos_stdlib::test_helper::GasParameters, pub signer: moveos_stdlib::signer::GasParameters, pub move_module: moveos_stdlib::move_module::GasParameters, + pub object: moveos_stdlib::object::GasParameters, } impl GasParameters { @@ -36,6 +37,7 @@ impl GasParameters { test_helper: moveos_stdlib::test_helper::GasParameters::zeros(), signer: moveos_stdlib::signer::GasParameters::zeros(), move_module: moveos_stdlib::move_module::GasParameters::zeros(), + object: moveos_stdlib::object::GasParameters::zeros(), } } } @@ -90,6 +92,10 @@ pub fn all_natives(gas_params: GasParameters) -> NativeFunctionTable { "move_module", moveos_stdlib::move_module::make_all(gas_params.move_module) ); + add_natives!( + "object_ref", + moveos_stdlib::object::make_all(gas_params.object) + ); let moveos_native_fun_table = make_table_from_iter(MOVEOS_STD_ADDRESS, natives); native_fun_table.extend(moveos_native_fun_table); diff --git a/moveos/moveos-stdlib/src/natives/moveos_stdlib/mod.rs b/moveos/moveos-stdlib/src/natives/moveos_stdlib/mod.rs index 8b3b22504c..f731b6d7a7 100644 --- a/moveos/moveos-stdlib/src/natives/moveos_stdlib/mod.rs +++ b/moveos/moveos-stdlib/src/natives/moveos_stdlib/mod.rs @@ -4,6 +4,7 @@ pub mod bcs; pub mod event; pub mod move_module; +pub mod object; pub mod raw_table; pub mod rlp; pub mod signer; diff --git a/moveos/moveos-stdlib/src/natives/moveos_stdlib/object.rs b/moveos/moveos-stdlib/src/natives/moveos_stdlib/object.rs new file mode 100644 index 0000000000..64b53d55eb --- /dev/null +++ b/moveos/moveos-stdlib/src/natives/moveos_stdlib/object.rs @@ -0,0 +1,145 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::errors::PartialVMResult; +use move_core_types::gas_algebra::InternalGas; +use move_vm_runtime::native_functions::{NativeContext, NativeFunction}; +use move_vm_types::{ + loaded_data::runtime_types::Type, + natives::function::NativeResult, + values::{GlobalValue, Struct, Value}, +}; +use moveos_types::{ + moveos_std::object_ref::ObjectRef, + state::{MoveState, PlaceholderStruct}, +}; +use smallvec::smallvec; +use std::{collections::VecDeque, sync::Arc}; + +use crate::natives::helpers::make_module_natives; + +#[derive(Debug, Clone)] +pub struct AsRefGasParameters { + pub base: InternalGas, +} + +impl AsRefGasParameters { + pub fn zeros() -> Self { + Self { + base: InternalGas::zero(), + } + } +} + +/*************************************************************************************************** + * native fun as_ref_inner + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[inline] +fn native_as_ref_inner( + gas_params: &AsRefGasParameters, + context: &mut NativeContext, + ty_args: Vec, + mut arguments: VecDeque, +) -> PartialVMResult { + debug_assert!(ty_args.len() == 1); + debug_assert!(arguments.len() == 1); + + let object_id = arguments.pop_back().unwrap(); + let object_ref = borrow_object_reference(context, object_id, &ty_args[0])?; + Ok(NativeResult::ok(gas_params.base, smallvec![object_ref])) +} + +pub fn make_native_as_ref_inner(gas_params: AsRefGasParameters) -> NativeFunction { + Arc::new(move |context, ty_args, args| native_as_ref_inner(&gas_params, context, ty_args, args)) +} + +#[derive(Debug, Clone)] +pub struct AsMutRefGasParameters { + pub base: InternalGas, +} + +impl AsMutRefGasParameters { + pub fn zeros() -> Self { + Self { + base: InternalGas::zero(), + } + } +} + +/*************************************************************************************************** + * native fun as_mut_ref_inner + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[inline] +fn native_as_mut_ref_inner( + gas_params: &AsMutRefGasParameters, + context: &mut NativeContext, + ty_args: Vec, + mut arguments: VecDeque, +) -> PartialVMResult { + debug_assert!(ty_args.len() == 1); + debug_assert!(arguments.len() == 1); + + let object_id = arguments.pop_back().unwrap(); + let object_ref = borrow_object_reference(context, object_id, &ty_args[0])?; + Ok(NativeResult::ok(gas_params.base, smallvec![object_ref])) +} + +pub fn make_native_as_mut_ref_inner(gas_params: AsMutRefGasParameters) -> NativeFunction { + Arc::new(move |context, ty_args, args| { + native_as_mut_ref_inner(&gas_params, context, ty_args, args) + }) +} + +fn borrow_object_reference( + context: &mut NativeContext, + object_id: Value, + ref_type: &Type, +) -> PartialVMResult { + let gv = GlobalValue::cached(Value::struct_(Struct::pack(vec![object_id])))?; + + let type_tag = context.type_to_type_tag(ref_type)?; + let type_layout = context + .get_type_layout(&type_tag) + .map_err(|e| e.to_partial())?; + + debug_assert!( + ObjectRef::::type_layout_match(&type_layout), + "Expected a struct type with layout same as ObjectRef" + ); + + //TODO should we keep the GlobalValue in Context? + gv.borrow_global() +} + +#[derive(Debug, Clone)] +pub struct GasParameters { + pub as_ref_inner: AsRefGasParameters, + pub as_mut_ref_inner: AsMutRefGasParameters, +} + +impl GasParameters { + pub fn zeros() -> Self { + Self { + as_ref_inner: AsRefGasParameters::zeros(), + as_mut_ref_inner: AsMutRefGasParameters::zeros(), + } + } +} + +pub fn make_all(gas_params: GasParameters) -> impl Iterator { + let natives = [ + ("as_ref_inner", make_native_as_ref_inner(gas_params.as_ref_inner)), + ( + "as_mut_ref_inner", + make_native_as_mut_ref_inner(gas_params.as_mut_ref_inner), + ), + ]; + + make_module_natives(natives) +} diff --git a/moveos/moveos/src/vm/tx_argument_resolver.rs b/moveos/moveos/src/vm/tx_argument_resolver.rs index b197cbb694..f55a07afd9 100644 --- a/moveos/moveos/src/vm/tx_argument_resolver.rs +++ b/moveos/moveos/src/vm/tx_argument_resolver.rs @@ -109,6 +109,16 @@ where )) .finish(Location::Undefined)); } + if object.owner != self.ctx.tx_context.sender() { + return Err(PartialVMError::new(StatusCode::NO_ACCOUNT_ROLE) + .with_message(format!( + "Object owner mismatch, object owner:{:?}, sender:{:?}", + object.owner, + self.ctx.tx_context.sender() + )) + .finish(Location::Undefined)); + } + //TODO check the object is external object. } } } @@ -117,7 +127,7 @@ where pub fn load_argument(&mut self, _func: &LoadedFunctionInstantiation, _args: &[Vec]) { //TODO load the object argument to the session - // If the argument is `ObjectRef`, we need to change the Object to code owner object. + // If the argument is `ObjectRef`, we need to change the Object to internal object. // We need to refactor the raw table, migrate the TableData to StorageContext. } } From b4a7c10c74cb18e9900778f53cd05e031aa6a1b5 Mon Sep 17 00:00:00 2001 From: jolestar Date: Wed, 25 Oct 2023 20:59:34 +0800 Subject: [PATCH 05/18] [MoveosStd] Simpler the Object&ObjectRef logic --- .../tests/cases/object/basic.move | 4 +- .../tests/cases/table/basic.move | 2 +- crates/rooch-framework/doc/coin_store.md | 2 +- .../rooch-framework/sources/coin_store.move | 2 +- examples/simple_blog/sources/article.move | 2 +- .../moveos-stdlib/doc/account_storage.md | 2 +- .../moveos-stdlib/doc/context.md | 54 +++++++- .../moveos-stdlib/doc/object_ref.md | 115 +++--------------- .../sources/account_storage.move | 8 +- .../moveos-stdlib/sources/context.move | 25 +++- .../moveos-stdlib/sources/event.move | 8 +- .../moveos-stdlib/sources/object_ref.move | 41 ++----- .../src/natives/moveos_stdlib/object.rs | 5 +- moveos/moveos-verifier/src/metadata.rs | 10 +- moveos/moveos-verifier/src/verifier.rs | 11 +- moveos/moveos/src/vm/tx_argument_resolver.rs | 32 +++-- 16 files changed, 152 insertions(+), 171 deletions(-) diff --git a/crates/rooch-framework-tests/tests/cases/object/basic.move b/crates/rooch-framework-tests/tests/cases/object/basic.move index 5ac6041fa2..83a6384957 100644 --- a/crates/rooch-framework-tests/tests/cases/object/basic.move +++ b/crates/rooch-framework-tests/tests/cases/object/basic.move @@ -18,7 +18,7 @@ module test::m { assert!(x"7852c5dcbd87e82102dba0db36d44b5a9fb0006b3e828c0b5f0832f70a8ff6ee" == tx_hash, 1000); let obj_ref = context::new_object(ctx, S { v: 1}); debug::print(&obj_ref); - object_ref::to_external(obj_ref); + object_ref::drop(obj_ref); } public entry fun move_s_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef) { @@ -31,7 +31,7 @@ module test::m { public entry fun mint_cup(ctx: &mut Context) { let obj_ref = context::new_object(ctx, Cup { v: 2 }); debug::print(&obj_ref); - object_ref::to_external(obj_ref); + object_ref::drop(obj_ref); } public entry fun move_cup_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef>) { diff --git a/crates/rooch-framework-tests/tests/cases/table/basic.move b/crates/rooch-framework-tests/tests/cases/table/basic.move index 2001203ffd..2e007b2918 100644 --- a/crates/rooch-framework-tests/tests/cases/table/basic.move +++ b/crates/rooch-framework-tests/tests/cases/table/basic.move @@ -33,7 +33,7 @@ module test::m { public fun save_to_object_storage(ctx: &mut Context, kv: KVStore) : ObjectID { let object_ref = context::new_object(ctx, kv); let object_id = object_ref::id(&object_ref); - object_ref::to_external(object_ref); + object_ref::drop(object_ref); object_id } } diff --git a/crates/rooch-framework/doc/coin_store.md b/crates/rooch-framework/doc/coin_store.md index 476da8a317..fda6524ec6 100644 --- a/crates/rooch-framework/doc/coin_store.md +++ b/crates/rooch-framework/doc/coin_store.md @@ -373,7 +373,7 @@ Only the CoinType module can freeze or unfreeze a CoinStore by the frozen: bool, ) { assert!(context::exist_object<CoinStore>(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound)); - let coin_store_object = context::borrow_object_mut<CoinStore>(ctx, coin_store_id); + let coin_store_object = context::borrow_object_mut_extend<CoinStore>(ctx, coin_store_id); object_ref::borrow_mut(coin_store_object).frozen = frozen; }
diff --git a/crates/rooch-framework/sources/coin_store.move b/crates/rooch-framework/sources/coin_store.move index afd8c6188d..dd5ab855b0 100644 --- a/crates/rooch-framework/sources/coin_store.move +++ b/crates/rooch-framework/sources/coin_store.move @@ -101,7 +101,7 @@ module rooch_framework::coin_store { frozen: bool, ) { assert!(context::exist_object(ctx, coin_store_id), error::invalid_argument(ErrorCoinStoreNotFound)); - let coin_store_object = context::borrow_object_mut(ctx, coin_store_id); + let coin_store_object = context::borrow_object_mut_extend(ctx, coin_store_id); object_ref::borrow_mut(coin_store_object).frozen = frozen; } diff --git a/examples/simple_blog/sources/article.move b/examples/simple_blog/sources/article.move index a3061109ef..aa4f5893d6 100644 --- a/examples/simple_blog/sources/article.move +++ b/examples/simple_blog/sources/article.move @@ -62,7 +62,7 @@ module simple_blog::article { }; event::emit(ctx, article_created_event); object_ref::transfer(&mut article_ref, owner_addr); - object_ref::to_external(article_ref); + object_ref::drop(article_ref); id } diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md b/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md index f599982b15..74d2b7a997 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md @@ -201,7 +201,7 @@ Create a new account storage space }; let obj = context::new_object_with_id(ctx, object_id, account_storage); object_ref::transfer_extend(&mut obj, account); - object_ref::to_external(obj); + object_ref::drop(obj); }
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md index 49c91b9187..941097ee7e 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md @@ -9,6 +9,7 @@ and let developers customize the storage - [Struct `Context`](#0x2_context_Context) +- [Constants](#@Constants_0) - [Function `tx_context`](#0x2_context_tx_context) - [Function `tx_context_mut`](#0x2_context_tx_context_mut) - [Function `sender`](#0x2_context_sender) @@ -23,15 +24,18 @@ and let developers customize the storage - [Function `tx_result`](#0x2_context_tx_result) - [Function `borrow_object`](#0x2_context_borrow_object) - [Function `borrow_object_mut`](#0x2_context_borrow_object_mut) +- [Function `borrow_object_mut_extend`](#0x2_context_borrow_object_mut_extend) - [Function `exist_object`](#0x2_context_exist_object) - [Function `new_object`](#0x2_context_new_object) - [Function `new_object_with_id`](#0x2_context_new_object_with_id) - [Function `new_singleton_object`](#0x2_context_new_singleton_object) -
use 0x1::option;
+
use 0x1::error;
+use 0x1::option;
 use 0x2::object;
 use 0x2::object_ref;
+use 0x2::signer;
 use 0x2::storage_context;
 use 0x2::tx_context;
 use 0x2::tx_meta;
@@ -78,6 +82,20 @@ The Context can not be drop or store, so developers ne
 
 
 
+
+
+## Constants
+
+
+
+
+
+
+
const ErrorObjectOwnerNotMatch: u64 = 1;
+
+ + + ## Function `tx_context` @@ -381,6 +399,7 @@ Get a value from the context map ## Function `borrow_object` Borrow Object from object store with object_id +Any one can borrow an &ObjectRef from the global object storage
public fun borrow_object<T: key>(self: &context::Context, object_id: object::ObjectID): &object_ref::ObjectRef<T>
@@ -407,9 +426,38 @@ Borrow Object from object store with object_id
 ## Function `borrow_object_mut`
 
 Borrow mut Object from object store with object_id
+Only the owner can borrow an &mut ObjectRef from the global object storage
+
+
+
public fun borrow_object_mut<T: key>(self: &mut context::Context, owner: &signer, object_id: object::ObjectID): &mut object_ref::ObjectRef<T>
+
+ + + +
+Implementation + + +
public fun borrow_object_mut<T: key>(self: &mut Context, owner: &signer, object_id: ObjectID): &mut ObjectRef<T> {
+    let object_entity = storage_context::borrow_mut<T>(&mut self.storage_context, object_id);
+    let owner_address = signer::address_of(owner);
+    assert!(object::owner(object_entity) == owner_address, error::permission_denied(ErrorObjectOwnerNotMatch));
+    object_ref::as_mut_ref(object_entity)
+}
+
+ + + +
+ + + +## Function `borrow_object_mut_extend` + +The module of T can borrow mut Object from object store with any object_id -
public fun borrow_object_mut<T: key>(self: &mut context::Context, object_id: object::ObjectID): &mut object_ref::ObjectRef<T>
+
public fun borrow_object_mut_extend<T: key>(self: &mut context::Context, object_id: object::ObjectID): &mut object_ref::ObjectRef<T>
 
@@ -418,7 +466,7 @@ Borrow mut Object from object store with object_id Implementation -
public fun borrow_object_mut<T: key>(self: &mut Context, object_id: ObjectID): &mut ObjectRef<T> {
+
public fun borrow_object_mut_extend<T: key>(self: &mut Context, object_id: ObjectID) : &mut ObjectRef<T> {
     let object_entity = storage_context::borrow_mut<T>(&mut self.storage_context, object_id);
     object_ref::as_mut_ref(object_entity)
 }
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md
index 3278457aa6..30a70cd942 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md
+++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md
@@ -9,13 +9,10 @@
 -  [Function `new_internal`](#0x2_object_ref_new_internal)
 -  [Function `as_ref`](#0x2_object_ref_as_ref)
 -  [Function `as_mut_ref`](#0x2_object_ref_as_mut_ref)
--  [Function `to_external`](#0x2_object_ref_to_external)
 -  [Function `borrow`](#0x2_object_ref_borrow)
--  [Function `borrow_extend`](#0x2_object_ref_borrow_extend)
 -  [Function `borrow_mut`](#0x2_object_ref_borrow_mut)
--  [Function `borrow_mut_extend`](#0x2_object_ref_borrow_mut_extend)
 -  [Function `remove`](#0x2_object_ref_remove)
--  [Function `remove_extend`](#0x2_object_ref_remove_extend)
+-  [Function `drop`](#0x2_object_ref_drop)
 -  [Function `transfer`](#0x2_object_ref_transfer)
 -  [Function `transfer_extend`](#0x2_object_ref_transfer_extend)
 -  [Function `id`](#0x2_object_ref_id)
@@ -130,34 +127,6 @@ It likes ObjectID, but it contains the type information of the object.
 
 
 
-
-
-
-
-## Function `to_external`
-
-Drop the ObjectRef, and make the object to be a external object.
-The external object can be used as transaction argument
-
-
-
public fun to_external<T: key>(self: object_ref::ObjectRef<T>)
-
- - - -
-Implementation - - -
public fun to_external<T: key>(self: ObjectRef<T>){
-    let ObjectRef{id} = self;
-    let obj = raw_table::borrow_mut_from_global<T>(&id);
-    object::set_external(obj, true);
-}
-
- - -
@@ -167,32 +136,7 @@ The external object can be used as transaction argument Borrow the object value -
public fun borrow<T: store, key>(self: &object_ref::ObjectRef<T>): &T
-
- - - -
-Implementation - - -
public fun borrow<T: key + store>(self: &ObjectRef<T>): &T {
-    let obj = raw_table::borrow_from_global<T>(&self.id);
-    object::borrow(obj)
-}
-
- - - -
- - - -## Function `borrow_extend` - - - -
public fun borrow_extend<T: key>(self: &object_ref::ObjectRef<T>): &T
+
public fun borrow<T: key>(self: &object_ref::ObjectRef<T>): &T
 
@@ -201,7 +145,7 @@ Borrow the object value Implementation -
public fun borrow_extend<T: key>(self: &ObjectRef<T>): &T {
+
public fun borrow<T: key>(self: &ObjectRef<T>): &T {
     let obj = raw_table::borrow_from_global<T>(&self.id);
     object::borrow(obj)
 }
@@ -218,7 +162,7 @@ Borrow the object value
 Borrow the object mutable value
 
 
-
public fun borrow_mut<T: store, key>(self: &mut object_ref::ObjectRef<T>): &mut T
+
public fun borrow_mut<T: key>(self: &mut object_ref::ObjectRef<T>): &mut T
 
@@ -227,32 +171,7 @@ Borrow the object mutable value Implementation -
public fun borrow_mut<T: key + store>(self: &mut ObjectRef<T>): &mut T {
-    let obj = raw_table::borrow_mut_from_global<T>(&self.id);
-    object::borrow_mut(obj)
-}
-
- - - - - - - -## Function `borrow_mut_extend` - - - -
public fun borrow_mut_extend<T: key>(self: &mut object_ref::ObjectRef<T>): &mut T
-
- - - -
-Implementation - - -
public fun borrow_mut_extend<T: key>(self: &mut ObjectRef<T>): &mut T {
+
public fun borrow_mut<T: key>(self: &mut ObjectRef<T>): &mut T {
     let obj = raw_table::borrow_mut_from_global<T>(&self.id);
     object::borrow_mut(obj)
 }
@@ -267,9 +186,10 @@ Borrow the object mutable value
 ## Function `remove`
 
 Remove the object from the global storage, and return the object value
+This function is only can be called by the module of T.
 
 
-
public fun remove<T: store, key>(self: object_ref::ObjectRef<T>): T
+
public fun remove<T: key>(self: object_ref::ObjectRef<T>): T
 
@@ -278,7 +198,7 @@ Remove the object from the global storage, and return the object value Implementation -
public fun remove<T: key + store>(self: ObjectRef<T>) : T {
+
public fun remove<T: key>(self: ObjectRef<T>) : T {
     let ObjectRef{id} = self;
     let object = raw_table::remove_from_global(&id);
     let (_id, _owner, value) = object::unpack(object);
@@ -290,13 +210,15 @@ Remove the object from the global storage, and return the object value
 
 
- + -## Function `remove_extend` +## Function `drop` +Directly drop the ObjectRef, the object will can not be removed from the object storage. +If you want to remove the object, please use remove function. -
public fun remove_extend<T: key>(self: object_ref::ObjectRef<T>): T
+
public fun drop<T: key>(self: object_ref::ObjectRef<T>)
 
@@ -305,11 +227,8 @@ Remove the object from the global storage, and return the object value Implementation -
public fun remove_extend<T: key>(self: ObjectRef<T>) : T {
-    let ObjectRef{id} = self;
-    let object = raw_table::remove_from_global(&id);
-    let (_id, _owner, value) = object::unpack(object);
-    value
+
public fun drop<T: key>(self: ObjectRef<T>) {
+    let ObjectRef{id:_} = self;
 }
 
@@ -321,6 +240,8 @@ Remove the object from the global storage, and return the object value ## Function `transfer` +Transfer the object to the new owner +Only the T with store can be directly transferred.
public fun transfer<T: store, key>(self: &mut object_ref::ObjectRef<T>, new_owner: address)
@@ -346,6 +267,8 @@ Remove the object from the global storage, and return the object value
 
 ## Function `transfer_extend`
 
+Transfer the object to the new owner
+This function is for the module of T to extend the transfer function.
 
 
 
public fun transfer_extend<T: key>(self: &mut object_ref::ObjectRef<T>, new_owner: address)
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move b/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move
index 01a858dbcb..4e84a8fded 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move
+++ b/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move
@@ -55,7 +55,7 @@ module moveos_std::account_storage {
         };
         let obj = context::new_object_with_id(ctx, object_id, account_storage);
         object_ref::transfer_extend(&mut obj, account);
-        object_ref::to_external(obj);
+        object_ref::drop(obj);
     }
 
     /// check if account storage eixst
@@ -75,13 +75,13 @@ module moveos_std::account_storage {
     fun borrow_account_storage(ctx: &Context, account: address): &AccountStorage{
         let object_id = object::address_to_object_id(account);
         let object = context::borrow_object(ctx, object_id);
-        object_ref::borrow_extend(object)
+        object_ref::borrow(object)
     }
 
     fun borrow_account_storage_mut(ctx: &mut Context, account: address): &mut AccountStorage{
         let object_id = object::address_to_object_id(account);
-        let object = context::borrow_object_mut(ctx, object_id);
-        object_ref::borrow_mut_extend(object)
+        let object = context::borrow_object_mut_extend(ctx, object_id);
+        object_ref::borrow_mut(object)
     }
 
     /// Borrow a resource from the AccountStorage
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move
index b6b4a5eded..4ad76943c1 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move
+++ b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move
@@ -7,18 +7,22 @@
 module moveos_std::context {
 
     use std::option::Option;
+    use std::error;
     use moveos_std::storage_context::{Self, StorageContext};
     use moveos_std::tx_context::{Self, TxContext};
     use moveos_std::object::{Self, ObjectID};
     use moveos_std::object_ref::{Self, ObjectRef};
     use moveos_std::tx_meta::{TxMeta};
     use moveos_std::tx_result::{TxResult};
+    use moveos_std::signer;
 
     friend moveos_std::table;
     friend moveos_std::type_table;
     friend moveos_std::account_storage;
     friend moveos_std::event;
 
+    const ErrorObjectOwnerNotMatch: u64 = 1;
+
     /// Information about the global context include TxContext and StorageContext
     /// We can not put the StorageContext to TxContext, because object module depends on tx_context module,
     /// and storage_context module depends on object module.
@@ -93,16 +97,25 @@ module moveos_std::context {
 
     // Wrap functions for StorageContext
 
-    #[private_generics(T)]
     /// Borrow Object from object store with object_id
+    /// Any one can borrow an &ObjectRef from the global object storage
     public fun borrow_object(self: &Context, object_id: ObjectID): &ObjectRef {
         let object_entity = storage_context::borrow(&self.storage_context, object_id);
         object_ref::as_ref(object_entity)
     }
 
-    #[private_generics(T)]
     /// Borrow mut Object from object store with object_id
-    public fun borrow_object_mut(self: &mut Context, object_id: ObjectID): &mut ObjectRef {
+    /// Only the owner can borrow an &mut ObjectRef from the global object storage
+    public fun borrow_object_mut(self: &mut Context, owner: &signer, object_id: ObjectID): &mut ObjectRef {
+        let object_entity = storage_context::borrow_mut(&mut self.storage_context, object_id);
+        let owner_address = signer::address_of(owner);
+        assert!(object::owner(object_entity) == owner_address, error::permission_denied(ErrorObjectOwnerNotMatch));
+        object_ref::as_mut_ref(object_entity)
+    }
+
+    #[private_generics(T)]
+    /// The module of T can borrow mut Object from object store with any object_id
+    public fun borrow_object_mut_extend(self: &mut Context, object_id: ObjectID) : &mut ObjectRef {
         let object_entity = storage_context::borrow_mut(&mut self.storage_context, object_id);
         object_ref::as_mut_ref(object_entity)
     }
@@ -176,14 +189,14 @@ module moveos_std::context {
         let ref = new_object(&mut ctx, TestObjectValue{value: 1});
         
         {
-            let obj_value = object_ref::borrow_mut_extend(&mut ref);
+            let obj_value = object_ref::borrow_mut(&mut ref);
             obj_value.value = 2;
         };
         {
-            let obj_value = object_ref::borrow_extend(&ref);
+            let obj_value = object_ref::borrow(&ref);
             assert!(obj_value.value == 2, 1000);
         };
-        object_ref::to_external(ref);
+        object_ref::drop(ref);
         drop_test_context(ctx);
     }
 }
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move
index 2daff4cbd6..743caca82b 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move
+++ b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move
@@ -42,14 +42,14 @@ module moveos_std::event {
     fun borrow_event_handle(ctx: &Context): &EventHandle {
         let event_handle_id = derive_event_handle_id();
         let object = context::borrow_object(ctx, event_handle_id);
-        object_ref::borrow_extend(object)
+        object_ref::borrow(object)
     }
 
     /// Borrow a mut event handle from the object storage
     fun borrow_event_handle_mut(ctx: &mut Context): &mut EventHandle {
         let event_handle_id = derive_event_handle_id();
-        let object = context::borrow_object_mut(ctx, event_handle_id);
-        object_ref::borrow_mut_extend(object)
+        let object = context::borrow_object_mut_extend(ctx, event_handle_id);
+        object_ref::borrow_mut(object)
     }
 
     /// Get event handle owner
@@ -85,7 +85,7 @@ module moveos_std::event {
         let type_info = type_info::type_of();
         let owner = type_info::account_address(&type_info);
         object_ref::transfer_extend(&mut obj, owner);
-        object_ref::to_external(obj);
+        object_ref::drop(obj);
     }
 
     public fun ensure_event_handle(ctx: &mut Context) {
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move
index 57738f5792..0704d0d450 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move
+++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move
@@ -33,61 +33,44 @@ module moveos_std::object_ref {
     native fun as_ref_inner(object_id: ObjectID): &T;
     native fun as_mut_ref_inner(object_id: ObjectID): &mut T;
 
-    #[private_generics(T)]
-    /// Drop the ObjectRef, and make the object to be a external object.
-    /// The external object can be used as transaction argument
-    public fun to_external(self: ObjectRef){
-        let ObjectRef{id} = self;
-        let obj = raw_table::borrow_mut_from_global(&id);
-        object::set_external(obj, true);
-    }
-
     /// Borrow the object value
-    public fun borrow(self: &ObjectRef): &T {
-        let obj = raw_table::borrow_from_global(&self.id);
-        object::borrow(obj)
-    }
-
-    #[private_generics(T)]
-    public fun borrow_extend(self: &ObjectRef): &T {
+    public fun borrow(self: &ObjectRef): &T {
         let obj = raw_table::borrow_from_global(&self.id);
         object::borrow(obj)
     }
 
     /// Borrow the object mutable value
-    public fun borrow_mut(self: &mut ObjectRef): &mut T {
+    public fun borrow_mut(self: &mut ObjectRef): &mut T {
         let obj = raw_table::borrow_mut_from_global(&self.id);
         object::borrow_mut(obj)
     }
 
     #[private_generics(T)]
-    public fun borrow_mut_extend(self: &mut ObjectRef): &mut T {
-        let obj = raw_table::borrow_mut_from_global(&self.id);
-        object::borrow_mut(obj)
-    } 
-
     /// Remove the object from the global storage, and return the object value
-    public fun remove(self: ObjectRef) : T {
+    /// This function is only can be called by the module of `T`.
+    public fun remove(self: ObjectRef) : T {
         let ObjectRef{id} = self;
         let object = raw_table::remove_from_global(&id);
         let (_id, _owner, value) = object::unpack(object);
         value
     }
 
-    #[private_generics(T)]
-    public fun remove_extend(self: ObjectRef) : T {
-        let ObjectRef{id} = self;
-        let object = raw_table::remove_from_global(&id);
-        let (_id, _owner, value) = object::unpack(object);
-        value
+    /// Directly drop the ObjectRef, the object will can not be removed from the object storage.
+    /// If you want to remove the object, please use `remove` function.
+    public fun drop(self: ObjectRef) {
+        let ObjectRef{id:_} = self;
     }
 
+    /// Transfer the object to the new owner
+    /// Only the `T` with `store` can be directly transferred.
     public fun transfer(self: &mut ObjectRef, new_owner: address) {
         let obj = raw_table::borrow_mut_from_global(&self.id);
         object::set_owner(obj, new_owner);
     }
 
     #[private_generics(T)]
+    /// Transfer the object to the new owner
+    /// This function is for the module of `T` to extend the `transfer` function.
     public fun transfer_extend(self: &mut ObjectRef, new_owner: address) {
         let obj = raw_table::borrow_mut_from_global(&self.id);
         object::set_owner(obj, new_owner);
diff --git a/moveos/moveos-stdlib/src/natives/moveos_stdlib/object.rs b/moveos/moveos-stdlib/src/natives/moveos_stdlib/object.rs
index 64b53d55eb..4140592b02 100644
--- a/moveos/moveos-stdlib/src/natives/moveos_stdlib/object.rs
+++ b/moveos/moveos-stdlib/src/natives/moveos_stdlib/object.rs
@@ -134,7 +134,10 @@ impl GasParameters {
 
 pub fn make_all(gas_params: GasParameters) -> impl Iterator {
     let natives = [
-        ("as_ref_inner", make_native_as_ref_inner(gas_params.as_ref_inner)),
+        (
+            "as_ref_inner",
+            make_native_as_ref_inner(gas_params.as_ref_inner),
+        ),
         (
             "as_mut_ref_inner",
             make_native_as_mut_ref_inner(gas_params.as_mut_ref_inner),
diff --git a/moveos/moveos-verifier/src/metadata.rs b/moveos/moveos-verifier/src/metadata.rs
index 7d9d0a3386..93da9933dc 100644
--- a/moveos/moveos-verifier/src/metadata.rs
+++ b/moveos/moveos-verifier/src/metadata.rs
@@ -437,6 +437,7 @@ impl<'a> ExtendedChecker<'a> {
                     self.env
                         .get_struct(mid.qualified(*sid))
                         .get_full_name_with_address(),
+                    false,
                 ) =>
             {
                 // Specific struct types are allowed
@@ -470,7 +471,7 @@ impl<'a> ExtendedChecker<'a> {
                     .env
                     .get_struct(mid.qualified(*sid))
                     .get_full_name_with_address();
-                if is_allowed_input_struct(struct_name) {
+                if is_allowed_input_struct(struct_name, true) {
                     return true;
                 }
                 false
@@ -480,15 +481,16 @@ impl<'a> ExtendedChecker<'a> {
     }
 }
 
-pub fn is_allowed_input_struct(name: String) -> bool {
+pub fn is_allowed_input_struct(name: String, is_ref: bool) -> bool {
     matches!(
         name.as_str(),
         "0x1::string::String"
             | "0x1::ascii::String"
             | "0x2::object::ObjectID"
             | "0x2::context::Context"
-            | "0x2::object_ref::ObjectRef"
-    )
+    ) ||
+    // ObjectRef only support reference type
+     (is_ref && name.as_str() == "0x2::object_ref::ObjectRef")
 }
 
 // ----------------------------------------------------------------------------------
diff --git a/moveos/moveos-verifier/src/verifier.rs b/moveos/moveos-verifier/src/verifier.rs
index 9907222f51..cf71c0fcb3 100644
--- a/moveos/moveos-verifier/src/verifier.rs
+++ b/moveos/moveos-verifier/src/verifier.rs
@@ -240,10 +240,7 @@ fn check_transaction_input_type_at_publish(
         }
         Struct(sid) | StructInstantiation(sid, _) => {
             let struct_full_name = struct_full_name_from_sid(sid, module_bin_view);
-            if is_allowed_input_struct(struct_full_name) {
-                return true;
-            }
-            false
+            is_allowed_input_struct(struct_full_name, false)
         }
 
         _ => {
@@ -260,7 +257,7 @@ fn is_allowed_reference_types_at_publish(
     match bt {
         SignatureToken::Struct(sid) | SignatureToken::StructInstantiation(sid, _) => {
             let struct_full_name = struct_full_name_from_sid(sid, module_bin_view);
-            is_allowed_input_struct(struct_full_name)
+            is_allowed_input_struct(struct_full_name, true)
         }
         _ => false,
     }
@@ -302,7 +299,7 @@ where
         Struct(idx) | StructInstantiation(idx, _) => {
             if let Some(st) = session.get_struct_type(*idx) {
                 let full_name = format!("{}::{}", st.module.short_str_lossless(), st.name);
-                is_allowed_input_struct(full_name)
+                is_allowed_input_struct(full_name, false)
             } else {
                 false
             }
@@ -339,7 +336,7 @@ where
             );
             if let Some(st) = st_option {
                 let full_name = format!("{}::{}", st.module.short_str_lossless(), st.name);
-                is_allowed_input_struct(full_name)
+                is_allowed_input_struct(full_name, true)
             } else {
                 false
             }
diff --git a/moveos/moveos/src/vm/tx_argument_resolver.rs b/moveos/moveos/src/vm/tx_argument_resolver.rs
index f55a07afd9..6f27c37823 100644
--- a/moveos/moveos/src/vm/tx_argument_resolver.rs
+++ b/moveos/moveos/src/vm/tx_argument_resolver.rs
@@ -109,16 +109,29 @@ where
                             ))
                             .finish(Location::Undefined));
                     }
-                    if object.owner != self.ctx.tx_context.sender() {
-                        return Err(PartialVMError::new(StatusCode::NO_ACCOUNT_ROLE)
-                            .with_message(format!(
-                                "Object owner mismatch, object owner:{:?}, sender:{:?}",
-                                object.owner,
-                                self.ctx.tx_context.sender()
-                            ))
-                            .finish(Location::Undefined));
+                    match paramter {
+                        Type::Reference(_r) => {
+                            // Any one can get any &ObjectRef
+                        }
+                        Type::MutableReference(_r) => {
+                            // Only the owner can get &mut ObjectRef
+                            if object.owner != self.ctx.tx_context.sender() {
+                                return Err(PartialVMError::new(StatusCode::NO_ACCOUNT_ROLE)
+                                    .with_message(format!(
+                                        "Object owner mismatch, object owner:{:?}, sender:{:?}",
+                                        object.owner,
+                                        self.ctx.tx_context.sender()
+                                    ))
+                                    .finish(Location::Undefined));
+                            }
+                        }
+                        _ => {
+                            return Err(PartialVMError::new(StatusCode::TYPE_MISMATCH)
+                                .with_message(
+                                    "Object type only support `&ObjectRef` and `&mut Object`, do not support `Object`".to_string())
+                                .finish(Location::Undefined));
+                        }
                     }
-                    //TODO check the object is external object.
                 }
             }
         }
@@ -127,7 +140,6 @@ where
 
     pub fn load_argument(&mut self, _func: &LoadedFunctionInstantiation, _args: &[Vec]) {
         //TODO load the object argument to the session
-        // If the argument is `ObjectRef`, we need to change the Object to internal object.
         // We need to refactor the raw table, migrate the TableData to StorageContext.
     }
 }

From d7021974b156aa9020433cca6cb4060c553c69d2 Mon Sep 17 00:00:00 2001
From: jolestar 
Date: Thu, 26 Oct 2023 00:19:46 +0800
Subject: [PATCH 06/18] fix test

---
 .../tests/cases/object/basic.exp              | 28 +++-----------
 .../tests/cases/object/basic.move             | 37 ++++++-------------
 .../tests/cases/object/object_cap.exp         | 12 +++---
 crates/rooch-framework/doc/coin_store.md      | 17 +++++----
 .../rooch-framework/sources/coin_store.move   |  9 +++--
 .../sources/tests/coin_store_test.move        |  3 +-
 .../cases/private_generics_direct_call.exp    |  6 +--
 .../cases/private_generics_direct_call.move   | 10 +----
 .../cases/private_generics_indirect_call.exp  | 24 ++++++------
 .../cases/private_generics_indirect_call.move | 17 +++++----
 10 files changed, 66 insertions(+), 97 deletions(-)

diff --git a/crates/rooch-framework-tests/tests/cases/object/basic.exp b/crates/rooch-framework-tests/tests/cases/object/basic.exp
index 80f6ddeaea..7ca1714e5b 100644
--- a/crates/rooch-framework-tests/tests/cases/object/basic.exp
+++ b/crates/rooch-framework-tests/tests/cases/object/basic.exp
@@ -1,32 +1,16 @@
-processed 10 tasks
+processed 6 tasks
 
-task 1 'publish'. lines 3-45:
+task 1 'publish'. lines 3-43:
 status EXECUTED
 
-task 2 'run'. lines 47-47:
+task 2 'run'. lines 45-45:
 status EXECUTED
 
-task 3 'view_object'. lines 49-51:
+task 3 'view_object'. lines 47-49:
 Object { id: ObjectID(ae43e34e51db9c833ab50dd9aa8b27106519e5bbfd533737306e7b69ef253647), owner: 0000000000000000000000000000000000000000000000000000000000000043, value: AnnotatedMoveStruct { abilities: [Store, Key, ], type_: StructTag { address: 0000000000000000000000000000000000000000000000000000000000000042, module: Identifier("m"), name: Identifier("S"), type_params: [] }, value: [(Identifier("v"), U8(1))] } }
 
-task 4 'run'. lines 53-53:
+task 4 'run'. lines 51-51:
 status EXECUTED
 
-task 5 'view_object'. lines 55-58:
+task 5 'view_object'. lines 53-53:
 Object { id: ObjectID(0bbaf311ae6768a532b1f9dee65b1758a7bb1114fd57df8fa94cb2d1cb5f6896), owner: 0000000000000000000000000000000000000000000000000000000000000043, value: AnnotatedMoveStruct { abilities: [Store, Key, ], type_: StructTag { address: 0000000000000000000000000000000000000000000000000000000000000042, module: Identifier("m"), name: Identifier("Cup"), type_params: [Struct(StructTag { address: 0000000000000000000000000000000000000000000000000000000000000042, module: Identifier("m"), name: Identifier("S"), type_params: [] })] }, value: [(Identifier("v"), U8(2))] } }
-
-task 6 'run'. lines 60-60:
-status EXECUTED
-
-task 7 'view'. lines 62-64:
-store key 0x42::m::S {
-    v: 1u8
-}
-
-task 8 'run'. lines 66-66:
-status EXECUTED
-
-task 9 'view'. lines 68-68:
-store key 0x42::m::Cup<0x42::m::S> {
-    v: 2u8
-}
diff --git a/crates/rooch-framework-tests/tests/cases/object/basic.move b/crates/rooch-framework-tests/tests/cases/object/basic.move
index 83a6384957..7c914a3825 100644
--- a/crates/rooch-framework-tests/tests/cases/object/basic.move
+++ b/crates/rooch-framework-tests/tests/cases/object/basic.move
@@ -4,8 +4,7 @@
 
 module test::m {
     use moveos_std::context::{Self, Context};
-    use moveos_std::object_ref::{Self, ObjectRef};
-    use moveos_std::account_storage;
+    use moveos_std::object_ref;
     use std::debug;
 
     struct S has store, key { v: u8 }
@@ -21,12 +20,13 @@ module test::m {
         object_ref::drop(obj_ref);
     }
 
-    public entry fun move_s_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef) {
-        let object_id = object_ref::id(&object_s);
-        debug::print(&object_id);
-        let value = object_ref::remove(object_s);
-        account_storage::global_move_to(ctx, &sender, value);
-    }
+    //We can not use `ObjectRef` as transaction argument now.
+    // public entry fun move_s_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef) {
+    //     let object_id = object_ref::id(&object_s);
+    //     debug::print(&object_id);
+    //     let value = object_ref::remove(object_s);
+    //     account_storage::global_move_to(ctx, &sender, value);
+    // }
 
     public entry fun mint_cup(ctx: &mut Context) {
         let obj_ref = context::new_object(ctx, Cup { v: 2 });
@@ -34,10 +34,10 @@ module test::m {
         object_ref::drop(obj_ref);
     }
 
-    public entry fun move_cup_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef>) {
-        let value = object_ref::remove(object_s);
-        account_storage::global_move_to(ctx, &sender, value);
-    }
+    // public entry fun move_cup_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef>) {
+    //     let value = object_ref::remove(object_s);
+    //     account_storage::global_move_to(ctx, &sender, value);
+    // }
 }
 
 // Mint S to A.
@@ -51,16 +51,3 @@ module test::m {
 //# run test::m::mint_cup --type-args test::m::S --signers A
 
 //# view_object --object-id 0x0bbaf311ae6768a532b1f9dee65b1758a7bb1114fd57df8fa94cb2d1cb5f6896
-
-// Move S to global.
-//Currently, we use @address to pass object argument to the transaction, define a new way to pass object argument to the transaction.
-
-//# run test::m::move_s_to_global --signers A --args @0xae43e34e51db9c833ab50dd9aa8b27106519e5bbfd533737306e7b69ef253647
-
-//# view --address A --resource test::m::S
-
-// Move Cup to global.
-
-//# run test::m::move_cup_to_global --signers A  --type-args test::m::S --args @0x0bbaf311ae6768a532b1f9dee65b1758a7bb1114fd57df8fa94cb2d1cb5f6896
-
-//# view --address A --resource test::m::Cup
diff --git a/crates/rooch-framework-tests/tests/cases/object/object_cap.exp b/crates/rooch-framework-tests/tests/cases/object/object_cap.exp
index 5d5edb4c05..8ac786adbf 100644
--- a/crates/rooch-framework-tests/tests/cases/object/object_cap.exp
+++ b/crates/rooch-framework-tests/tests/cases/object/object_cap.exp
@@ -4,16 +4,16 @@ task 1 'publish'. lines 3-21:
 status EXECUTED
 
 task 2 'run'. lines 22-34:
-Error: error: resource type "TestObject" in function "0x2::context::new_object" not defined in current module or not allowed
+Error: error: resource type "TestStruct" in function "0x2::context::new_object" not defined in current module or not allowed
    ┌─ /tmp/tempfile:29:23
    │
-29 │         let obj_ref = context::new_object(ctx, object);
+29 │         let obj_ref = context::new_object(ctx, object);
    │                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: resource type "TestObject" in function "0x2::context::remove_object" not defined in current module or not allowed
-   ┌─ /tmp/tempfile:30:42
+error: resource type "TestStruct" in function "0x2::object_ref::remove" not defined in current module or not allowed
+   ┌─ /tmp/tempfile:30:27
    │
-30 │         let (_id, _owner, test_object) = context::remove_object(ctx, object_ref::id(&obj_ref));
-   │                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+30 │         let test_struct = object_ref::remove(obj_ref);
+   │                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
diff --git a/crates/rooch-framework/doc/coin_store.md b/crates/rooch-framework/doc/coin_store.md
index fda6524ec6..c31ee489df 100644
--- a/crates/rooch-framework/doc/coin_store.md
+++ b/crates/rooch-framework/doc/coin_store.md
@@ -10,7 +10,7 @@
 -  [Constants](#@Constants_0)
 -  [Function `create_coin_store`](#0x3_coin_store_create_coin_store)
 -  [Function `create_coin_store_extend`](#0x3_coin_store_create_coin_store_extend)
--  [Function `drop_coin_store`](#0x3_coin_store_drop_coin_store)
+-  [Function `remove_coin_store`](#0x3_coin_store_remove_coin_store)
 -  [Function `coin_type`](#0x3_coin_store_coin_type)
 -  [Function `balance`](#0x3_coin_store_balance)
 -  [Function `is_frozen`](#0x3_coin_store_is_frozen)
@@ -196,14 +196,14 @@ This function is for the CoinType module to extend
 
 
 
-
+
 
-## Function `drop_coin_store`
+## Function `remove_coin_store`
 
-Drop the CoinStore, return the Coin in balance
+Remove the CoinStore Object, return the Coin in balance
 
 
-
public fun drop_coin_store<CoinType: key>(coin_store: coin_store::CoinStore): coin::Coin<CoinType>
+
public fun remove_coin_store<CoinType: key>(coin_store_object: object_ref::ObjectRef<coin_store::CoinStore>): coin::Coin<CoinType>
 
@@ -212,10 +212,13 @@ Drop the CoinStore, return the Coin in balance Implementation -
public fun drop_coin_store<CoinType: key>(coin_store: CoinStore) : Coin<CoinType> {
+
public fun remove_coin_store<CoinType: key>(coin_store_object: ObjectRef<CoinStore>) : Coin<CoinType> {
+    let coin_store = object_ref::remove(coin_store_object);
     let coin_type = type_info::type_name<CoinType>();
     assert!(coin_store.coin_type == coin_type, error::invalid_argument(ErrorCoinTypeAndStoreMismatch));
-    let CoinStore{coin_type:_, balance, frozen:_} = coin_store;
+    let CoinStore{coin_type:_, balance, frozen} = coin_store;
+    // Cannot remove a frozen CoinStore, because if we allow this, the frozen is meaningless
+    assert!(!frozen, error::permission_denied(ErrorCoinStoreIsFrozen));
     let Balance{value} = balance;
     coin::pack<CoinType>(value)
 }
diff --git a/crates/rooch-framework/sources/coin_store.move b/crates/rooch-framework/sources/coin_store.move
index dd5ab855b0..1d09f7a78d 100644
--- a/crates/rooch-framework/sources/coin_store.move
+++ b/crates/rooch-framework/sources/coin_store.move
@@ -58,11 +58,14 @@ module rooch_framework::coin_store {
     }
     
 
-     /// Drop the CoinStore, return the Coin in balance 
-    public fun drop_coin_store(coin_store: CoinStore) : Coin {
+     /// Remove the CoinStore Object, return the Coin in balance 
+    public fun remove_coin_store(coin_store_object: ObjectRef) : Coin {
+        let coin_store = object_ref::remove(coin_store_object);
         let coin_type = type_info::type_name();
         assert!(coin_store.coin_type == coin_type, error::invalid_argument(ErrorCoinTypeAndStoreMismatch));
-        let CoinStore{coin_type:_, balance, frozen:_} = coin_store;
+        let CoinStore{coin_type:_, balance, frozen} = coin_store;
+        // Cannot remove a frozen CoinStore, because if we allow this, the frozen is meaningless
+        assert!(!frozen, error::permission_denied(ErrorCoinStoreIsFrozen));
         let Balance{value} = balance;
         coin::pack(value)
     }
diff --git a/crates/rooch-framework/sources/tests/coin_store_test.move b/crates/rooch-framework/sources/tests/coin_store_test.move
index 6f28f347f1..bd17c878a9 100644
--- a/crates/rooch-framework/sources/tests/coin_store_test.move
+++ b/crates/rooch-framework/sources/tests/coin_store_test.move
@@ -64,8 +64,7 @@ module rooch_framework::coin_store_test{
             assert!(coin_store::balance(coin_store) == 90, 3);
             coin::burn_extend(&mut ctx, coin_withdrawn);
         };
-        let coin_store = object_ref::remove(coin_store_ref);
-        let coin = coin_store::drop_coin_store(coin_store);
+        let coin = coin_store::remove_coin_store(coin_store_ref);
         assert!(coin::value(&coin) == 90, 4);
         coin::burn_extend(&mut ctx, coin);
         assert!(coin::supply(&ctx) == 0, 5);
diff --git a/crates/rooch-integration-test-runner/tests/cases/private_generics_direct_call.exp b/crates/rooch-integration-test-runner/tests/cases/private_generics_direct_call.exp
index de97279cb9..7d274502c3 100644
--- a/crates/rooch-integration-test-runner/tests/cases/private_generics_direct_call.exp
+++ b/crates/rooch-integration-test-runner/tests/cases/private_generics_direct_call.exp
@@ -1,12 +1,12 @@
 processed 4 tasks
 
-task 1 'publish'. lines 3-30:
+task 1 'publish'. lines 3-22:
 status EXECUTED
 
-task 2 'run'. lines 32-40:
+task 2 'run'. lines 24-32:
 status EXECUTED
 
-task 3 'view'. lines 42-44:
+task 3 'view'. lines 34-36:
 store key 0x42::test::Foo {
     x: 500
 }
diff --git a/crates/rooch-integration-test-runner/tests/cases/private_generics_direct_call.move b/crates/rooch-integration-test-runner/tests/cases/private_generics_direct_call.move
index 5d31a27914..83980029bf 100644
--- a/crates/rooch-integration-test-runner/tests/cases/private_generics_direct_call.move
+++ b/crates/rooch-integration-test-runner/tests/cases/private_generics_direct_call.move
@@ -4,9 +4,7 @@
 module creator::test {
     use std::string;
     use moveos_std::account_storage;
-    use moveos_std::context::{Self, Context};
-    use moveos_std::object::ObjectID;
-    use std::debug;
+    use moveos_std::context::{Context};
 
     struct Foo has key, store {
         x: u64,
@@ -21,12 +19,6 @@ module creator::test {
         let _ = string::utf8(b"account_storage");
         publish_foo(ctx, s)
     }
-
-    public fun call_moveos_std(ctx: &mut Context, sender: &signer, object_id: ObjectID) {
-        debug::print(&object_id);
-        let (_id,_owner,value) = context::remove_object(ctx, object_id);
-        account_storage::global_move_to(ctx, sender, value);
-    }
 }
 
 //# run --signers creator
diff --git a/crates/rooch-integration-test-runner/tests/cases/private_generics_indirect_call.exp b/crates/rooch-integration-test-runner/tests/cases/private_generics_indirect_call.exp
index f5e9e81ce4..b44ca4b5ee 100644
--- a/crates/rooch-integration-test-runner/tests/cases/private_generics_indirect_call.exp
+++ b/crates/rooch-integration-test-runner/tests/cases/private_generics_indirect_call.exp
@@ -1,25 +1,25 @@
 processed 3 tasks
 
-task 1 'publish'. lines 3-8:
+task 1 'publish'. lines 3-11:
 status EXECUTED
 
-task 2 'publish'. lines 10-38:
-Error: error: resource type "KeyStruct" in function "0x2::context::remove_object" not defined in current module or not allowed
-   ┌─ /tmp/tempfile:31:34
+task 2 'publish'. lines 13-39:
+Error: error: resource type "KeyStruct" in function "0x2::context::new_object" not defined in current module or not allowed
+   ┌─ /tmp/tempfile:32:22
    │
-31 │         let (_id,_owner,value) = context::remove_object(ctx, object_id);
-   │                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+32 │         let object = context::new_object(ctx, test0::new_key_struct(100));
+   │                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: resource type "KeyStruct" in function "0x2::account_storage::global_move_to" not defined in current module or not allowed
-   ┌─ /tmp/tempfile:32:9
+error: resource type "KeyStruct" in function "0x2::object_ref::remove" not defined in current module or not allowed
+   ┌─ /tmp/tempfile:33:27
    │
-32 │         account_storage::global_move_to(ctx, sender, value);
-   │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+33 │         let _key_struct = object_ref::remove(object);
+   │                           ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: resource type "KeyStruct" in function "0x42::test::publish_foo" not defined in current module or not allowed
-   ┌─ /tmp/tempfile:27:9
+   ┌─ /tmp/tempfile:29:9
    │
-27 │         publish_foo(ctx, s)
+29 │         publish_foo(ctx, s)
    │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
diff --git a/crates/rooch-integration-test-runner/tests/cases/private_generics_indirect_call.move b/crates/rooch-integration-test-runner/tests/cases/private_generics_indirect_call.move
index be1ebd7527..ec86753cb0 100644
--- a/crates/rooch-integration-test-runner/tests/cases/private_generics_indirect_call.move
+++ b/crates/rooch-integration-test-runner/tests/cases/private_generics_indirect_call.move
@@ -2,19 +2,21 @@
 
 //# publish
 module creator::test0 {
-    struct KeyStruct has key {
+    struct KeyStruct has key, drop {
         x: u64,
     }
+    public fun new_key_struct(x: u64) : KeyStruct {
+        KeyStruct { x }
+    }
 }
 
 //# publish
 module creator::test {
     use std::string;
-    use std::debug;
-    use creator::test0::KeyStruct;
+    use creator::test0::{Self, KeyStruct};
     use moveos_std::account_storage;
     use moveos_std::context::{Self, Context};
-    use moveos_std::object::ObjectID;
+    use moveos_std::object_ref;
 
     struct Foo has key {
         x: u64,
@@ -30,9 +32,8 @@ module creator::test {
         publish_foo(ctx, s)
     }
 
-    public fun call_moveos_std(ctx: &mut Context, sender: &signer, object_id: ObjectID) {
-        debug::print(&object_id);
-        let (_id,_owner,value) = context::remove_object(ctx, object_id);
-        account_storage::global_move_to(ctx, sender, value);
+    public fun call_moveos_std(ctx: &mut Context) {
+        let object = context::new_object(ctx, test0::new_key_struct(100));
+        let _key_struct = object_ref::remove(object);
     }
 }

From f952fa373db8ba91ffa75168e322a8c42e700f0f Mon Sep 17 00:00:00 2001
From: jolestar 
Date: Thu, 26 Oct 2023 00:37:17 +0800
Subject: [PATCH 07/18] fix example/simple_blog

---
 examples/simple_blog/sources/article.move | 29 +++++++-----------
 examples/simple_blog/sources/blog.move    | 37 ++++++++++++-----------
 2 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/examples/simple_blog/sources/article.move b/examples/simple_blog/sources/article.move
index aa4f5893d6..d1f474ef28 100644
--- a/examples/simple_blog/sources/article.move
+++ b/examples/simple_blog/sources/article.move
@@ -41,7 +41,7 @@ module simple_blog::article {
         owner: &signer,
         title: String,
         body: String,
-    ): ObjectID {
+    ): ObjectRef
{ assert!(std::string::length(&title) <= 200, error::invalid_argument(ErrorDataTooLong)); assert!(std::string::length(&body) <= 2000, error::invalid_argument(ErrorDataTooLong)); @@ -51,19 +51,18 @@ module simple_blog::article { body, }; let owner_addr = signer::address_of(owner); - let article_ref = context::new_object( + let article_obj = context::new_object( ctx, article, ); - let id = object_ref::id(&article_ref); + let id = object_ref::id(&article_obj); let article_created_event = ArticleCreatedEvent { id, }; event::emit(ctx, article_created_event); - object_ref::transfer(&mut article_ref, owner_addr); - object_ref::drop(article_ref); - id + object_ref::transfer(&mut article_obj, owner_addr); + article_obj } /// Update article @@ -94,14 +93,8 @@ module simple_blog::article { ctx: &mut Context, article_obj: ObjectRef
, ) { - - //let owner_address = signer::address_of(owner); let id = object_ref::id(&article_obj); let article = object_ref::remove(article_obj); - //let (id, owner, article) = context::remove_object
(ctx, id); - - // only article owner can delete the article - //assert!(owner == owner_address, error::permission_denied(ErrorNotOwnerAccount)); let article_deleted_event = ArticleDeletedEvent { id, @@ -123,18 +116,18 @@ module simple_blog::article { /// get article version - public fun version(article_obj: &ObjectRef
): u64 { - object_ref::borrow(article_obj).version + public fun version(article: &Article): u64 { + article.version } /// get article title - public fun title(article_obj: &ObjectRef
): String { - object_ref::borrow(article_obj).title + public fun title(article: &Article): String { + article.title } /// get article body - public fun body(article_obj: &ObjectRef
): String { - object_ref::borrow(article_obj).body + public fun body(article: &Article): String { + article.body } } diff --git a/examples/simple_blog/sources/blog.move b/examples/simple_blog/sources/blog.move index 6e49957eb8..2af22ec087 100644 --- a/examples/simple_blog/sources/blog.move +++ b/examples/simple_blog/sources/blog.move @@ -17,7 +17,7 @@ module simple_blog::blog { struct MyBlog has key { name: String, - articles: vector, + articles: vector>, } /// This init function is called when the module is published @@ -47,32 +47,34 @@ module simple_blog::blog { myblog.name = blog_name; } - fun add_article_to_myblog(ctx: &mut Context, owner: &signer, article_id: ObjectID) { + fun add_article_to_myblog(ctx: &mut Context, owner: &signer, article_obj: ObjectRef
) { let owner_address = signer::address_of(owner); // if blog not exist, create it if(!account_storage::global_exists(ctx, owner_address)){ create_blog(ctx, owner); }; let myblog = account_storage::global_borrow_mut(ctx, owner_address); - vector::push_back(&mut myblog.articles, article_id); + vector::push_back(&mut myblog.articles, article_obj); } - fun delete_article_from_myblog(ctx: &mut Context, owner: &signer, article_id: ObjectID) { + fun delete_article_from_myblog(ctx: &mut Context, owner: &signer, article_id: ObjectID): ObjectRef
{ let owner_address = signer::address_of(owner); let myblog = account_storage::global_borrow_mut(ctx, owner_address); - let (contains, index) = vector::index_of(&myblog.articles, &article_id); - assert!(contains, error::not_found(ErrorNotFound)); - vector::remove(&mut myblog.articles, index); + let idx = 0; + while(idx < vector::length(&myblog.articles)){ + let article_obj = vector::borrow(&myblog.articles, idx); + if(object_ref::id(article_obj) == article_id){ + return vector::remove(&mut myblog.articles, idx) + }; + idx = idx + 1; + }; + abort error::not_found(ErrorNotFound) } /// Get owner's blog's articles - public fun get_blog_articles(ctx: &Context, owner_address: address): vector { - if(!account_storage::global_exists(ctx, owner_address)){ - vector::empty() - }else{ - let myblog = account_storage::global_borrow(ctx, owner_address); - myblog.articles - } + public fun get_blog_articles(ctx: &Context, owner_address: address): &vector> { + let myblog = account_storage::global_borrow(ctx, owner_address); + &myblog.articles } public entry fun create_article( @@ -96,11 +98,10 @@ module simple_blog::blog { public entry fun delete_article( ctx: &mut Context, - owner: signer, - article_obj: ObjectRef
, + owner: &signer, + article_id: ObjectID, ) { - let id = object_ref::id(&article_obj); + let article_obj = delete_article_from_myblog(ctx, owner, article_id); article::delete_article(ctx, article_obj); - delete_article_from_myblog(ctx, &owner, id); } } From f70469a72b435f3a551837474b1541bb7fcbb7f4 Mon Sep 17 00:00:00 2001 From: jolestar Date: Thu, 26 Oct 2023 01:02:23 +0800 Subject: [PATCH 08/18] update basic_object --- examples/basic_object/Move.toml | 4 +- examples/basic_object/README.md | 109 +------------ .../basic_object/sources/public_object.move | 3 + examples/basic_object/sources/something.move | 143 ------------------ .../sources/something_aggregate.move | 37 ----- .../sources/something_do_logic.move | 29 ---- 6 files changed, 8 insertions(+), 317 deletions(-) create mode 100644 examples/basic_object/sources/public_object.move delete mode 100644 examples/basic_object/sources/something.move delete mode 100644 examples/basic_object/sources/something_aggregate.move delete mode 100644 examples/basic_object/sources/something_do_logic.move diff --git a/examples/basic_object/Move.toml b/examples/basic_object/Move.toml index 68b8c12da6..f085f26af8 100644 --- a/examples/basic_object/Move.toml +++ b/examples/basic_object/Move.toml @@ -6,9 +6,9 @@ version = "0.0.1" MoveosStdlib = { local = "../../moveos/moveos-stdlib/moveos-stdlib" } [addresses] -rooch_examples = "_" +basic_object = "_" moveos_std = "0x2" rooch_framework = "0x3" [dev-addresses] -rooch_examples = "0x42" +basic_object = "0x42" diff --git a/examples/basic_object/README.md b/examples/basic_object/README.md index 73a30596e3..4a30738be8 100644 --- a/examples/basic_object/README.md +++ b/examples/basic_object/README.md @@ -1,109 +1,6 @@ # A Basic Object Example -## Start local server +TODO -1. add fixtures/config.yml to the ROOCH_CONFIG environment variable. -2. Start a local server: -```shell -rooch server start -``` - -## Publish the example - -Open another terminal, publish this example (Note that the placeholder `{ACCOUNT_ADDRESS}` should be replaced with the address of your account): - -```shell -# rooch account list # List your accounts, pick one -# rooch account create # Create a account if no accounts listed -rooch move publish --named-addresses rooch_examples={ACCOUNT_ADDRESS} -``` - -## Run functions - -Run a function to create something on-chain: - -```shell -rooch move run --function {ACCOUNT_ADDRESS}::something_aggregate::create_something --args 1u32 2u128 --sender-account {ACCOUNT_ADDRESS} -``` - -## Query using JSON RPC APIs - -### Get events by event handle type - -Run this command to get events by event handle type: - -```shell -curl --location --request POST 'http://localhost:50051' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "id":101, - "jsonrpc":"2.0", - "method":"rooch_getEventsByEventHandle", - "params": [ - "{EVENT_HANDLE_TYPE}", "{CURSOR}", "{LIMIT}" -] -}' -``` - -An example: - -``` -curl --location 'http://localhost:50051' \ ---header 'Content-Type: application/json' \ ---data '{ - "id": 101, - "jsonrpc": "2.0", - "method": "rooch_getEventsByEventHandle", - "params": [ - "0xb4321fa441b5d9fdefb71f82856a56447451f7b1ba9478747b07e9f26b34c87::something::SomethingCreated", 1, 2 - ] -}' -``` - -The output is similar to the following (Note that the ID of the created object appears where the placeholder `{ID_OF_CREATED_OBJECT}` is located.): - -```json -{"jsonrpc":"2.0","result":[{"sender":"0000000000000000000000000000000000000000000000000000000000000000","event_data":"0x0b00395f380aa20ab634291b1fe8705e8ba94ce5bfab66dbe436865cc40974ef0100000002000000000000000000000000000000","parsed_event_data":{"abilities":8,"type":"0x565d5717526aecec1f9d464867f7d92d6eae2dc8ca73a0dc2613dd185d3d7bc7::something::SomethingCreated","value":{"i":1,"j":"2","obj_id":"{ID_OF_CREATED_OBJECT}"}},"type_tag":"0x565d5717526aecec1f9d464867f7d92d6eae2dc8ca73a0dc2613dd185d3d7bc7::something::SomethingCreated","event_index":3,"event_id":{"event_handle_id":"0x53f32af12dc9236eb67f1c064cf55ee8891a90040f71ba17422cfdd91eb7358b","event_seq":0}}],"id":101} -``` - -### Get annotated states by object ID - -To retrieve information of an object through the RPC interface (The placeholder `OBJECT_ID` should be replaced with the value output above.): - -```shell -curl --location --request POST 'http://127.0.0.1:50051/' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "id":101, - "jsonrpc":"2.0", - "method":"rooch_getAnnotatedStates", - "params":["/object/{OBJECT_ID}"] -}' -``` - -The output is similar to the following (Note that the handle of the Table embedded in the created object appears where the placeholder `{HANDLE_OF_CREATED_OBJECT_TABLE}` is located.): - -```json -{"jsonrpc":"2.0","result":[{"state":{"value":"0x0b00395f380aa20ab634291b1fe8705e8ba94ce5bfab66dbe436865cc40974ef565d5717526aecec1f9d464867f7d92d6eae2dc8ca73a0dc2613dd185d3d7bc70100000002000000000000000000000000000000ba90d115eab89e3167e4fb9a489a46606189e8ad474d5e232fd70568923effff0b64dc6ef8063f3819a2458643c86d2869dfc5064b6e33212ca27742887d6dc0","value_type":"0x1::object::Object<0x565d5717526aecec1f9d464867f7d92d6eae2dc8ca73a0dc2613dd185d3d7bc7::something::SomethingProperties>"},"move_value":{"abilities":0,"type":"0x1::object::Object<0x565d5717526aecec1f9d464867f7d92d6eae2dc8ca73a0dc2613dd185d3d7bc7::something::SomethingProperties>","value":{"id":"0xb00395f380aa20ab634291b1fe8705e8ba94ce5bfab66dbe436865cc40974ef","owner":"0x565d5717526aecec1f9d464867f7d92d6eae2dc8ca73a0dc2613dd185d3d7bc7","value":{"abilities":8,"type":"0x565d5717526aecec1f9d464867f7d92d6eae2dc8ca73a0dc2613dd185d3d7bc7::something::SomethingProperties","value":{"barTable":{"abilities":4,"type":"0x1::table::Table","value":{"handle":"{HANDLE_OF_CREATED_OBJECT_TABLE}"}},"fooTable":{"abilities":4,"type":"0x1::table::Table<0x1::string::String, 0x1::string::String>","value":{"handle":"0xba90d115eab89e3167e4fb9a489a46606189e8ad474d5e232fd70568923effff"}},"i":1,"j":"2"}}}}}],"id":101} -``` - -### Get table item - -To retrieve value of a table item through the RPC interface `rooch_getAnnotatedStates` (The placeholder `TABLE_HANDLE` should be replaced with the value output above.): - -```shell -curl --location --request POST 'http://127.0.0.1:50051/' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "id":101, - "jsonrpc":"2.0", - "method":"rooch_getAnnotatedStates", - "params":["/table/{TABLE_HANDLE}/0x01"] -}' -``` - -The output is similar to the following: - -```json -{"jsonrpc":"2.0","result":[{"state":{"value":"0x01000000000000000000000000000000","value_type":"u128"},"move_value":"1"}],"id":101} -``` +1. A Show different between `T: key+store` + `T: key` +2. Show different code style between use ObjectRef as argument of entry function or borrow it from context. \ No newline at end of file diff --git a/examples/basic_object/sources/public_object.move b/examples/basic_object/sources/public_object.move new file mode 100644 index 0000000000..aceb4089a9 --- /dev/null +++ b/examples/basic_object/sources/public_object.move @@ -0,0 +1,3 @@ +module basic_object::public_object{ + +} \ No newline at end of file diff --git a/examples/basic_object/sources/something.move b/examples/basic_object/sources/something.move deleted file mode 100644 index 2e2f127912..0000000000 --- a/examples/basic_object/sources/something.move +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) RoochNetwork -// SPDX-License-Identifier: Apache-2.0 - -module rooch_examples::something { - use std::string::String; - use moveos_std::event; - use moveos_std::object_ref::{Self, ObjectRef}; - use moveos_std::object::ObjectID; - use moveos_std::context::{Self, Context}; - use moveos_std::table::{Self, Table}; - - friend rooch_examples::something_aggregate; - friend rooch_examples::something_do_logic; - - struct SomethingProperties has key { - i: u32, - j: u128, - fooTable: Table, - barTable: Table, - } - - /// get object id - public fun id(obj: &ObjectRef): ObjectID { - object_ref::id(obj) - } - - /// get property 'i' from object - public fun i(obj: &ObjectRef): u32 { - object_ref::borrow(obj).i - } - - /// set property 'i' of object - public(friend) fun set_i(obj: &mut ObjectRef, i: u32) { - object_ref::borrow_mut(obj).i = i; - } - - public fun j(obj: &ObjectRef): u128 { - object_ref::borrow(obj).j - } - - public(friend) fun set_j(obj: &mut ObjectRef, j: u128) { - object_ref::borrow_mut(obj).j = j; - } - - struct SomethingCreated { - obj_id: ObjectID, - i: u32, - j: u128, - } - - struct KeyValuePair has store { - key: K, - value: V, - } - - struct BarTableItemAdded { - item: KeyValuePair - } - - struct FooTableItemAdded { - item: KeyValuePair - } - - public(friend) fun create_something( - ctx: &mut Context, - i: u32, - j: u128, - ): ObjectRef { - let value = new_something_properties(ctx, i, j); - let obj = context::new_object( - ctx, - value, - ); - event::emit(ctx, SomethingCreated { - obj_id: object_ref::id(&obj), - i, - j, - }); - obj - } - - fun new_something_properties( - ctx: &mut Context, - i: u32, - j: u128, - ): SomethingProperties { - let ps = SomethingProperties { - i, - j, - fooTable: table::new(ctx), - barTable: table::new(ctx), - }; - add_bar_table_item(ctx, &mut ps.barTable, 0, 0); - add_bar_table_item(ctx, &mut ps.barTable, 1, 1); - add_bar_table_item(ctx, &mut ps.barTable, 2, 2); - ps - } - - fun add_bar_table_item(ctx: &mut Context, - table: &mut Table, - key: u8, - val: u128 - ) { - table::add(table, key, val); - event::emit(ctx, BarTableItemAdded { - item: KeyValuePair { - key, - value: val, - } - }); - } - - public(friend) fun add_foo_table_item( - ctx: &mut Context, - obj: &mut ObjectRef, - key: String, - val: String - ) { - table::add(&mut object_ref::borrow_mut(obj).fooTable, key, val); - event::emit(ctx, FooTableItemAdded { - item: KeyValuePair { - key, - value: val, - } - }); - } - - public(friend) fun get_something( - ctx: &mut Context, - obj_id: ObjectID - ): ObjectRef { - let obj = context::borrow_object_mut(ctx, obj_id); - object_ref::new(obj) - } - - public(friend) fun remove_something( - ctx: &mut Context, - obj_id: ObjectID - ): SomethingProperties { - let (_id, _owner, value) = context::remove_object(ctx, obj_id); - value - } -} diff --git a/examples/basic_object/sources/something_aggregate.move b/examples/basic_object/sources/something_aggregate.move deleted file mode 100644 index a2e2ab129a..0000000000 --- a/examples/basic_object/sources/something_aggregate.move +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) RoochNetwork -// SPDX-License-Identifier: Apache-2.0 - -module rooch_examples::something_aggregate { - use std::string::String; - - use moveos_std::object::ObjectID; - use moveos_std::context::Context; - use rooch_examples::something; - use rooch_examples::something_do_logic; - - public entry fun create_something( - stoage_ctx: &mut Context, - i: u32, - j: u128, - ) { - something::create_something(stoage_ctx, i, j); - } - - public entry fun add_foo_table_item( - ctx: &mut Context, - object_id: ObjectID, - key: String, - val: String, - ) { - let obj = something::get_something(ctx, object_id); - something_do_logic::add_foo_table_item(ctx, obj, key, val); - } - - public entry fun remove_do_something_add( - ctx: &mut Context, - object_id: ObjectID, - ) { - let obj = something::get_something(ctx, object_id); - something_do_logic::do_something(obj); - } -} diff --git a/examples/basic_object/sources/something_do_logic.move b/examples/basic_object/sources/something_do_logic.move deleted file mode 100644 index f56c1c8ab1..0000000000 --- a/examples/basic_object/sources/something_do_logic.move +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) RoochNetwork -// SPDX-License-Identifier: Apache-2.0 - -module rooch_examples::something_do_logic { - use std::string::String; - use moveos_std::object_ref::ObjectRef; - use moveos_std::context::Context; - use rooch_examples::something::{Self, SomethingProperties}; - - friend rooch_examples::something_aggregate; - - public(friend) fun do_something(obj: ObjectRef): ObjectRef { - let i = something::i(&obj) + 1; - something::set_i(&mut obj, i); - let j = something::j(&obj) + 1; - something::set_j(&mut obj, j); - obj - } - - public(friend) fun add_foo_table_item( - ctx: &mut Context, - obj: ObjectRef, - key: String, - val: String - ): ObjectRef { - something::add_foo_table_item(ctx, &mut obj, key, val); - obj - } -} From 7dc11482fb80f59ee1c1f2c621086c6629cfe742 Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 14:15:02 +0800 Subject: [PATCH 09/18] [Object] define to_permanent to_shared to_frozen --- .../tests/cases/object/basic.move | 4 +- .../tests/cases/table/basic.move | 2 +- .../moveos-stdlib/doc/account_storage.md | 2 +- .../moveos-stdlib/doc/context.md | 10 +- .../moveos-stdlib/moveos-stdlib/doc/object.md | 166 ++++++++++++++---- .../moveos-stdlib/doc/object_ref.md | 94 +++++++++- .../sources/account_storage.move | 2 +- .../moveos-stdlib/sources/context.move | 12 +- .../moveos-stdlib/sources/event.move | 2 +- .../moveos-stdlib/sources/object.move | 42 +++-- .../moveos-stdlib/sources/object_ref.move | 29 ++- 11 files changed, 286 insertions(+), 79 deletions(-) diff --git a/crates/rooch-framework-tests/tests/cases/object/basic.move b/crates/rooch-framework-tests/tests/cases/object/basic.move index 7c914a3825..bd8fad95ee 100644 --- a/crates/rooch-framework-tests/tests/cases/object/basic.move +++ b/crates/rooch-framework-tests/tests/cases/object/basic.move @@ -17,7 +17,7 @@ module test::m { assert!(x"7852c5dcbd87e82102dba0db36d44b5a9fb0006b3e828c0b5f0832f70a8ff6ee" == tx_hash, 1000); let obj_ref = context::new_object(ctx, S { v: 1}); debug::print(&obj_ref); - object_ref::drop(obj_ref); + object_ref::to_permanent(obj_ref); } //We can not use `ObjectRef` as transaction argument now. @@ -31,7 +31,7 @@ module test::m { public entry fun mint_cup(ctx: &mut Context) { let obj_ref = context::new_object(ctx, Cup { v: 2 }); debug::print(&obj_ref); - object_ref::drop(obj_ref); + object_ref::to_permanent(obj_ref); } // public entry fun move_cup_to_global(ctx: &mut Context, sender: signer, object_s: ObjectRef>) { diff --git a/crates/rooch-framework-tests/tests/cases/table/basic.move b/crates/rooch-framework-tests/tests/cases/table/basic.move index 2e007b2918..f34a46dbfd 100644 --- a/crates/rooch-framework-tests/tests/cases/table/basic.move +++ b/crates/rooch-framework-tests/tests/cases/table/basic.move @@ -33,7 +33,7 @@ module test::m { public fun save_to_object_storage(ctx: &mut Context, kv: KVStore) : ObjectID { let object_ref = context::new_object(ctx, kv); let object_id = object_ref::id(&object_ref); - object_ref::drop(object_ref); + object_ref::to_permanent(object_ref); object_id } } diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md b/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md index 74d2b7a997..8737d9bc8b 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/account_storage.md @@ -201,7 +201,7 @@ Create a new account storage space }; let obj = context::new_object_with_id(ctx, object_id, account_storage); object_ref::transfer_extend(&mut obj, account); - object_ref::drop(obj); + object_ref::to_permanent(obj); }
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md index 941097ee7e..7bb35fffe8 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md @@ -426,7 +426,7 @@ Any one can borrow an &ObjectRef from the global object storage ## Function `borrow_object_mut` Borrow mut Object from object store with object_id -Only the owner can borrow an &mut ObjectRef from the global object storage +If the object is not shared, only the owner can borrow an &mut ObjectRef from the global object storage
public fun borrow_object_mut<T: key>(self: &mut context::Context, owner: &signer, object_id: object::ObjectID): &mut object_ref::ObjectRef<T>
@@ -440,8 +440,10 @@ Only the owner can borrow an &mut ObjectRef from the global object storage
 
 
public fun borrow_object_mut<T: key>(self: &mut Context, owner: &signer, object_id: ObjectID): &mut ObjectRef<T> {
     let object_entity = storage_context::borrow_mut<T>(&mut self.storage_context, object_id);
-    let owner_address = signer::address_of(owner);
-    assert!(object::owner(object_entity) == owner_address, error::permission_denied(ErrorObjectOwnerNotMatch));
+    if(!object::is_shared(object_entity)) {
+        let owner_address = signer::address_of(owner);
+        assert!(object::owner(object_entity) == owner_address, error::permission_denied(ErrorObjectOwnerNotMatch));
+    };
     object_ref::as_mut_ref(object_entity)
 }
 
@@ -545,7 +547,7 @@ Add the Object to the global object storage and return the ObjectRef
public(friend) fun new_object_with_id<T: key>(self: &mut Context, id: ObjectID, value: T) : ObjectRef<T> {
     let obj_entity = object::new(id, value);
-    object::set_owner(&mut obj_entity, sender(self));
+    object::transfer(&mut obj_entity, sender(self));
     let obj_ref = object_ref::new_internal(&mut obj_entity);
     storage_context::add(&mut self.storage_context, obj_entity);
     obj_ref
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md
index 1138480974..eb25ee1bb8 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md
+++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md
@@ -15,18 +15,22 @@ The differents with the Object in [Sui](https://github.com/MystenLabs/sui/blob/5
 -  [Constants](#@Constants_0)
 -  [Function `address_to_object_id`](#0x2_object_address_to_object_id)
 -  [Function `singleton_object_id`](#0x2_object_singleton_object_id)
--  [Function `code_owner_address`](#0x2_object_code_owner_address)
 -  [Function `new`](#0x2_object_new)
 -  [Function `borrow`](#0x2_object_borrow)
 -  [Function `borrow_mut`](#0x2_object_borrow_mut)
--  [Function `set_owner`](#0x2_object_set_owner)
--  [Function `set_external`](#0x2_object_set_external)
+-  [Function `transfer`](#0x2_object_transfer)
+-  [Function `transfer_to_system`](#0x2_object_transfer_to_system)
+-  [Function `to_shared`](#0x2_object_to_shared)
+-  [Function `is_shared`](#0x2_object_is_shared)
+-  [Function `to_frozen`](#0x2_object_to_frozen)
+-  [Function `is_frozen`](#0x2_object_is_frozen)
 -  [Function `id`](#0x2_object_id)
 -  [Function `owner`](#0x2_object_owner)
 -  [Function `unpack`](#0x2_object_unpack)
 
 
-
use 0x1::hash;
+
use 0x1::error;
+use 0x1::hash;
 use 0x2::address;
 use 0x2::bcs;
 use 0x2::type_info;
@@ -69,7 +73,7 @@ The object can not be copied, droped and stored. It only can be consumed by Stor
 value: T
 
 
- Whether the object is external + A flag to indicate whether the object is shared or frozen
@@ -109,11 +113,20 @@ An object ID ## Constants - + -
const CODE_OWNER_ADDRESS: address = 0;
+
const ErrorInvalidOwnerAddress: u64 = 1;
+
+ + + + + + + +
const SYSTEM_OWNER_ADDRESS: address = 0;
 
@@ -175,13 +188,14 @@ Generate a new ObjectID from an address - + -## Function `code_owner_address` +## Function `new` +Create a new object, the object is owned by owner -
public fun code_owner_address(): address
+
public(friend) fun new<T: key>(id: object::ObjectID, value: T): object::Object<T>
 
@@ -190,8 +204,9 @@ Generate a new ObjectID from an address Implementation -
public fun code_owner_address(): address {
-    CODE_OWNER_ADDRESS
+
public(friend) fun new<T: key>(id: ObjectID, value: T): Object<T> {
+    let owner = SYSTEM_OWNER_ADDRESS;
+    Object<T>{id, value, owner}
 }
 
@@ -199,14 +214,13 @@ Generate a new ObjectID from an address - + -## Function `new` +## Function `borrow` -Create a new object, the object is owned by owner -
public(friend) fun new<T: key>(id: object::ObjectID, value: T): object::Object<T>
+
public(friend) fun borrow<T>(self: &object::Object<T>): &T
 
@@ -215,9 +229,8 @@ Create a new object, the object is owned by owner Implementation -
public(friend) fun new<T: key>(id: ObjectID, value: T): Object<T> {
-    let owner = CODE_OWNER_ADDRESS;
-    Object<T>{id, value, owner}
+
public(friend) fun borrow<T>(self: &Object<T>): &T {
+    &self.value
 }
 
@@ -225,13 +238,13 @@ Create a new object, the object is owned by owner - + -## Function `borrow` +## Function `borrow_mut` -
public(friend) fun borrow<T>(self: &object::Object<T>): &T
+
public(friend) fun borrow_mut<T>(self: &mut object::Object<T>): &mut T
 
@@ -240,8 +253,8 @@ Create a new object, the object is owned by owner Implementation -
public(friend) fun borrow<T>(self: &Object<T>): &T {
-    &self.value
+
public(friend) fun borrow_mut<T>(self: &mut Object<T>): &mut T {
+    &mut self.value
 }
 
@@ -249,13 +262,13 @@ Create a new object, the object is owned by owner - + -## Function `borrow_mut` +## Function `transfer` -
public(friend) fun borrow_mut<T>(self: &mut object::Object<T>): &mut T
+
public(friend) fun transfer<T>(self: &mut object::Object<T>, owner: address)
 
@@ -264,8 +277,9 @@ Create a new object, the object is owned by owner Implementation -
public(friend) fun borrow_mut<T>(self: &mut Object<T>): &mut T {
-    &mut self.value
+
public(friend) fun transfer<T>(self: &mut Object<T>, owner: address) {
+    assert!(owner != SYSTEM_OWNER_ADDRESS, error::invalid_argument(ErrorInvalidOwnerAddress));
+    self.owner = owner;
 }
 
@@ -273,13 +287,13 @@ Create a new object, the object is owned by owner - + -## Function `set_owner` +## Function `transfer_to_system` -
public(friend) fun set_owner<T>(self: &mut object::Object<T>, owner: address)
+
public(friend) fun transfer_to_system<T>(self: &mut object::Object<T>)
 
@@ -288,8 +302,81 @@ Create a new object, the object is owned by owner Implementation -
public(friend) fun set_owner<T>(self: &mut Object<T>, owner: address) {
-    self.owner = owner;
+
public(friend) fun transfer_to_system<T>(self: &mut Object<T>){
+    self.owner = SYSTEM_OWNER_ADDRESS;
+}
+
+ + + + + + + +## Function `to_shared` + + + +
public(friend) fun to_shared<T>(_self: &mut object::Object<T>)
+
+ + + +
+Implementation + + +
public(friend) fun to_shared<T>(_self: &mut Object<T>) {
+    // TODO set the flag
+}
+
+ + + +
+ + + +## Function `is_shared` + + + +
public(friend) fun is_shared<T>(_self: &object::Object<T>): bool
+
+ + + +
+Implementation + + +
public(friend) fun is_shared<T>(_self: &Object<T>) : bool {
+    // TODO check the flag
+    false
+}
+
+ + + +
+ + + +## Function `to_frozen` + + + +
public(friend) fun to_frozen<T>(_self: &mut object::Object<T>)
+
+ + + +
+Implementation + + +
public(friend) fun to_frozen<T>(_self: &mut Object<T>) {
+    // TODO set the flag
 }
 
@@ -297,13 +384,13 @@ Create a new object, the object is owned by owner
- + -## Function `set_external` +## Function `is_frozen` -
public(friend) fun set_external<T>(_self: &mut object::Object<T>, _external: bool)
+
public(friend) fun is_frozen<T>(_self: &object::Object<T>): bool
 
@@ -312,8 +399,9 @@ Create a new object, the object is owned by owner Implementation -
public(friend) fun set_external<T>(_self: &mut Object<T>, _external: bool) {
-    //self.external = external;
+
public(friend) fun is_frozen<T>(_self: &Object<T>) : bool {
+    // TODO check the flag
+    false
 }
 
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md index 30a70cd942..67e642d5dd 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md @@ -6,20 +6,24 @@ - [Resource `ObjectRef`](#0x2_object_ref_ObjectRef) +- [Constants](#@Constants_0) - [Function `new_internal`](#0x2_object_ref_new_internal) - [Function `as_ref`](#0x2_object_ref_as_ref) - [Function `as_mut_ref`](#0x2_object_ref_as_mut_ref) - [Function `borrow`](#0x2_object_ref_borrow) - [Function `borrow_mut`](#0x2_object_ref_borrow_mut) - [Function `remove`](#0x2_object_ref_remove) -- [Function `drop`](#0x2_object_ref_drop) +- [Function `to_permanent`](#0x2_object_ref_to_permanent) +- [Function `to_shared`](#0x2_object_ref_to_shared) +- [Function `to_frozen`](#0x2_object_ref_to_frozen) - [Function `transfer`](#0x2_object_ref_transfer) - [Function `transfer_extend`](#0x2_object_ref_transfer_extend) - [Function `id`](#0x2_object_ref_id) - [Function `owner`](#0x2_object_ref_owner) -
use 0x2::object;
+
use 0x1::error;
+use 0x2::object;
 use 0x2::raw_table;
 
@@ -55,6 +59,20 @@ It likes ObjectID, but it contains the type information of the object. + + +## Constants + + + + + + +
const ErrorObjectFrozen: u64 = 1;
+
+ + + ## Function `new_internal` @@ -121,6 +139,7 @@ It likes ObjectID, but it contains the type information of the object.
public(friend) fun as_mut_ref<T: key>(object: &mut Object<T>) : &mut ObjectRef<T>{
+    assert!(!object::is_frozen(object), error::permission_denied(ErrorObjectFrozen));
     as_mut_ref_inner<ObjectRef<T>>(object::id(object))
 }
 
@@ -210,15 +229,15 @@ This function is only can be called by the module of T. - + -## Function `drop` +## Function `to_permanent` -Directly drop the ObjectRef, the object will can not be removed from the object storage. +Directly drop the ObjectRef, and make the Object permanent, the object will can not be removed from the object storage. If you want to remove the object, please use remove function. -
public fun drop<T: key>(self: object_ref::ObjectRef<T>)
+
public fun to_permanent<T: key>(self: object_ref::ObjectRef<T>)
 
@@ -227,13 +246,70 @@ If you want to remove the object, please use remove function. Implementation -
public fun drop<T: key>(self: ObjectRef<T>) {
+
public fun to_permanent<T: key>(self: ObjectRef<T>) {
     let ObjectRef{id:_} = self;
 }
 
+ + + + +## Function `to_shared` + +Make the Object shared, Any one can get the &mut ObjectRef from shared object +The shared object also can be removed from the object storage. + + +
public fun to_shared<T: key>(self: object_ref::ObjectRef<T>)
+
+ + + +
+Implementation + + +
public fun to_shared<T: key>(self: ObjectRef<T>) {
+    let obj = raw_table::borrow_mut_from_global<T>(&self.id);
+    object::to_shared(obj);
+    object::transfer_to_system(obj);
+    to_permanent(self);
+}
+
+ + + +
+ + + +## Function `to_frozen` + +Make the Object frozen, Any one can not get the &mut ObjectRef from frozen object + + +
public fun to_frozen<T: key>(self: object_ref::ObjectRef<T>)
+
+ + + +
+Implementation + + +
public fun to_frozen<T: key>(self: ObjectRef<T>) {
+    let obj = raw_table::borrow_mut_from_global<T>(&self.id);
+    object::to_frozen(obj);
+    object::transfer_to_system(obj);
+    to_permanent(self);
+}
+
+ + +
@@ -255,7 +331,7 @@ Only the T with store can be directly transferred.
public fun transfer<T: key + store>(self: &mut ObjectRef<T>, new_owner: address) {
     let obj = raw_table::borrow_mut_from_global<T>(&self.id);
-    object::set_owner(obj, new_owner);
+    object::transfer(obj, new_owner);
 }
 
@@ -282,7 +358,7 @@ This function is for the module of T to extend the transferpublic fun transfer_extend<T: key>(self: &mut ObjectRef<T>, new_owner: address) { let obj = raw_table::borrow_mut_from_global<T>(&self.id); - object::set_owner(obj, new_owner); + object::transfer(obj, new_owner); }
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move b/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move index 4e84a8fded..03978e90c4 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/account_storage.move @@ -55,7 +55,7 @@ module moveos_std::account_storage { }; let obj = context::new_object_with_id(ctx, object_id, account_storage); object_ref::transfer_extend(&mut obj, account); - object_ref::drop(obj); + object_ref::to_permanent(obj); } /// check if account storage eixst diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move index 4ad76943c1..2bd1f8055d 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move @@ -105,11 +105,13 @@ module moveos_std::context { } /// Borrow mut Object from object store with object_id - /// Only the owner can borrow an &mut ObjectRef from the global object storage + /// If the object is not shared, only the owner can borrow an &mut ObjectRef from the global object storage public fun borrow_object_mut(self: &mut Context, owner: &signer, object_id: ObjectID): &mut ObjectRef { let object_entity = storage_context::borrow_mut(&mut self.storage_context, object_id); - let owner_address = signer::address_of(owner); - assert!(object::owner(object_entity) == owner_address, error::permission_denied(ErrorObjectOwnerNotMatch)); + if(!object::is_shared(object_entity)) { + let owner_address = signer::address_of(owner); + assert!(object::owner(object_entity) == owner_address, error::permission_denied(ErrorObjectOwnerNotMatch)); + }; object_ref::as_mut_ref(object_entity) } @@ -137,7 +139,7 @@ module moveos_std::context { public(friend) fun new_object_with_id(self: &mut Context, id: ObjectID, value: T) : ObjectRef { let obj_entity = object::new(id, value); - object::set_owner(&mut obj_entity, sender(self)); + object::transfer(&mut obj_entity, sender(self)); let obj_ref = object_ref::new_internal(&mut obj_entity); storage_context::add(&mut self.storage_context, obj_entity); obj_ref @@ -196,7 +198,7 @@ module moveos_std::context { let obj_value = object_ref::borrow(&ref); assert!(obj_value.value == 2, 1000); }; - object_ref::drop(ref); + object_ref::to_permanent(ref); drop_test_context(ctx); } } diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move index 743caca82b..5b0e6a7a8f 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move @@ -85,7 +85,7 @@ module moveos_std::event { let type_info = type_info::type_of(); let owner = type_info::account_address(&type_info); object_ref::transfer_extend(&mut obj, owner); - object_ref::drop(obj); + object_ref::to_permanent(obj); } public fun ensure_event_handle(ctx: &mut Context) { diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move index f7cc79cdd5..d5d5ce3064 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move @@ -8,6 +8,7 @@ /// 2. The Object is a use case of the Hot Potato pattern in Move. Objects do not have any ability, so they cannot be drop, copy, or store, and can only be handled by StorageContext API after creation. module moveos_std::object { + use std::error; use std::hash; use moveos_std::type_info; use moveos_std::bcs; @@ -20,7 +21,9 @@ module moveos_std::object { friend moveos_std::object_ref; friend moveos_std::raw_table; - const CODE_OWNER_ADDRESS: address = @0x0; + const ErrorInvalidOwnerAddress:u64 = 1; + + const SYSTEM_OWNER_ADDRESS: address = @0x0; ///TODO rename to ObjectEntity /// Box style object @@ -30,8 +33,8 @@ module moveos_std::object { id: ObjectID, // The owner of the object owner: address, - /// Whether the object is external - //external: bool, + /// A flag to indicate whether the object is shared or frozen + //flag: u8, // The value of the object // The value must be the last field value: T, @@ -60,13 +63,9 @@ module moveos_std::object { ) } - public fun code_owner_address(): address { - CODE_OWNER_ADDRESS - } - /// Create a new object, the object is owned by `owner` public(friend) fun new(id: ObjectID, value: T): Object { - let owner = CODE_OWNER_ADDRESS; + let owner = SYSTEM_OWNER_ADDRESS; Object{id, value, owner} } @@ -78,14 +77,33 @@ module moveos_std::object { &mut self.value } - public(friend) fun set_owner(self: &mut Object, owner: address) { + public(friend) fun transfer(self: &mut Object, owner: address) { + assert!(owner != SYSTEM_OWNER_ADDRESS, error::invalid_argument(ErrorInvalidOwnerAddress)); self.owner = owner; } - public(friend) fun set_external(_self: &mut Object, _external: bool) { - //self.external = external; + public(friend) fun transfer_to_system(self: &mut Object){ + self.owner = SYSTEM_OWNER_ADDRESS; } + public(friend) fun to_shared(_self: &mut Object) { + // TODO set the flag + } + + public(friend) fun is_shared(_self: &Object) : bool { + // TODO check the flag + false + } + + public(friend) fun to_frozen(_self: &mut Object) { + // TODO set the flag + } + + public(friend) fun is_frozen(_self: &Object) : bool { + // TODO check the flag + false + } + public fun id(self: &Object): ObjectID { self.id } @@ -119,7 +137,7 @@ module moveos_std::object { let borrow_object = borrow_mut(&mut obj); assert!(borrow_object.count == object_count, 1001); - set_owner(&mut obj, @0x10); + transfer(&mut obj, @0x10); let obj_owner = owner(&obj); assert!(obj_owner != sender_addr, 1002); diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move index 0704d0d450..b1fbb5aece 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move @@ -3,11 +3,14 @@ module moveos_std::object_ref { + use std::error; use moveos_std::object::{Self, Object, ObjectID}; use moveos_std::raw_table; friend moveos_std::context; + const ErrorObjectFrozen: u64 = 1; + ///TODO rename to Object /// ObjectRef is a reference of the Object /// It likes ObjectID, but it contains the type information of the object. @@ -25,6 +28,7 @@ module moveos_std::object_ref { as_ref_inner>(object::id(object)) } public(friend) fun as_mut_ref(object: &mut Object) : &mut ObjectRef{ + assert!(!object::is_frozen(object), error::permission_denied(ErrorObjectFrozen)); as_mut_ref_inner>(object::id(object)) } @@ -55,17 +59,34 @@ module moveos_std::object_ref { value } - /// Directly drop the ObjectRef, the object will can not be removed from the object storage. + /// Directly drop the ObjectRef, and make the Object permanent, the object will can not be removed from the object storage. /// If you want to remove the object, please use `remove` function. - public fun drop(self: ObjectRef) { + public fun to_permanent(self: ObjectRef) { let ObjectRef{id:_} = self; } + /// Make the Object shared, Any one can get the &mut ObjectRef from shared object + /// The shared object also can be removed from the object storage. + public fun to_shared(self: ObjectRef) { + let obj = raw_table::borrow_mut_from_global(&self.id); + object::to_shared(obj); + object::transfer_to_system(obj); + to_permanent(self); + } + + /// Make the Object frozen, Any one can not get the &mut ObjectRef from frozen object + public fun to_frozen(self: ObjectRef) { + let obj = raw_table::borrow_mut_from_global(&self.id); + object::to_frozen(obj); + object::transfer_to_system(obj); + to_permanent(self); + } + /// Transfer the object to the new owner /// Only the `T` with `store` can be directly transferred. public fun transfer(self: &mut ObjectRef, new_owner: address) { let obj = raw_table::borrow_mut_from_global(&self.id); - object::set_owner(obj, new_owner); + object::transfer(obj, new_owner); } #[private_generics(T)] @@ -73,7 +94,7 @@ module moveos_std::object_ref { /// This function is for the module of `T` to extend the `transfer` function. public fun transfer_extend(self: &mut ObjectRef, new_owner: address) { let obj = raw_table::borrow_mut_from_global(&self.id); - object::set_owner(obj, new_owner); + object::transfer(obj, new_owner); } public fun id(self: &ObjectRef): ObjectID { From 6e64818ace01d2dd5ae55aafb78f4ea304cd8e5f Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 18:04:48 +0800 Subject: [PATCH 10/18] [MoveosStd] set create_object default owner to system --- .../rooch-framework/sources/account_coin_store.move | 1 + crates/rooch-framework/sources/coin_store.move | 11 ++++++++--- .../moveos-stdlib/moveos-stdlib/sources/context.move | 5 +++-- moveos/moveos-stdlib/moveos-stdlib/sources/event.move | 8 ++++---- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/crates/rooch-framework/sources/account_coin_store.move b/crates/rooch-framework/sources/account_coin_store.move index 5149e3334c..f9204fd7d5 100644 --- a/crates/rooch-framework/sources/account_coin_store.move +++ b/crates/rooch-framework/sources/account_coin_store.move @@ -286,6 +286,7 @@ module rooch_framework::account_coin_store { fun create_account_coin_store(ctx: &mut Context, addr: address) { let coin_store_ref = coin_store::create_coin_store_internal(ctx); + coin_store::transfer(&mut coin_store_ref, addr); let coin_stores = account_storage::global_borrow_mut(ctx, addr); let coin_type = type_info::type_name(); table::add(&mut coin_stores.coin_stores, coin_type, coin_store_ref); diff --git a/crates/rooch-framework/sources/coin_store.move b/crates/rooch-framework/sources/coin_store.move index 1d09f7a78d..12e86312f3 100644 --- a/crates/rooch-framework/sources/coin_store.move +++ b/crates/rooch-framework/sources/coin_store.move @@ -35,7 +35,7 @@ module rooch_framework::coin_store { /// A holder of a specific coin types. /// These are kept in a single resource to ensure locality of data. - struct CoinStore has key,store { + struct CoinStore has key { coin_type: string::String, balance: Balance, frozen: bool, @@ -57,8 +57,7 @@ module rooch_framework::coin_store { create_coin_store_internal(ctx) } - - /// Remove the CoinStore Object, return the Coin in balance + /// Remove the CoinStore Object, return the Coin in balance public fun remove_coin_store(coin_store_object: ObjectRef) : Coin { let coin_store = object_ref::remove(coin_store_object); let coin_type = type_info::type_name(); @@ -120,6 +119,12 @@ module rooch_framework::coin_store { }) } + // We do not allow to transfer a CoinStore to another account, CoinStore is default ownerd by the system. + // Only provide a internal function for account_coin_store. + public(friend) fun transfer(coin_store_obj: &mut ObjectRef, owner: address){ + object_ref::transfer_extend(coin_store_obj, owner) + } + fun check_coin_store_not_frozen(coin_store: &CoinStore) { assert!(!coin_store.frozen,error::permission_denied(ErrorCoinStoreIsFrozen)); } diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move index 2bd1f8055d..48573a924d 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/context.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/context.move @@ -130,8 +130,9 @@ module moveos_std::context { // Wrap functions for Object #[private_generics(T)] - /// Create a new Object, the default owner is the `sender` - /// Add the Object to the global object storage and return the ObjectRef + /// Create a new Object, Add the Object to the global object storage and return the ObjectRef + /// Note: the default owner is the `System`, the caller should explicitly transfer the Object to the owner. + /// The owner can get the `&mut ObjectRef` by `borrow_object_mut` public fun new_object(self: &mut Context, value: T): ObjectRef { let id = fresh_object_id(self); new_object_with_id(self, id, value) diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move index 5b0e6a7a8f..5de6c3f34c 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/event.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/event.move @@ -82,10 +82,10 @@ module moveos_std::event { }; //TODO refactor EventHandle with singleton Object. let obj = context::new_object_with_id(ctx, event_handle_id, event_handle); - let type_info = type_info::type_of(); - let owner = type_info::account_address(&type_info); - object_ref::transfer_extend(&mut obj, owner); - object_ref::to_permanent(obj); + // The event handle should be a shared object + // Any one can emit event to this handle + // TODO provide a emit event function with event handle + object_ref::to_shared(obj); } public fun ensure_event_handle(ctx: &mut Context) { From 8e830b3874c3a2c9cae53021e420cce52b8c104b Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 18:05:14 +0800 Subject: [PATCH 11/18] [Example] Refactor NFT example --- examples/nft/sources/collection.move | 186 ++++--------------- examples/nft/sources/nft.move | 262 +++++---------------------- 2 files changed, 87 insertions(+), 361 deletions(-) diff --git a/examples/nft/sources/collection.move b/examples/nft/sources/collection.move index 2d6844deeb..b0dc8fe2ce 100644 --- a/examples/nft/sources/collection.move +++ b/examples/nft/sources/collection.move @@ -4,13 +4,12 @@ module nft::collection{ use std::option; use std::option::Option; - use std::string::String; - use rooch_framework::display::{Self, Display}; - use moveos_std::object::{Self, ObjectID}; + use std::string::{Self, String}; + use rooch_framework::display; + use moveos_std::object::{ObjectID}; use moveos_std::event; use moveos_std::context::{Self, Context}; use moveos_std::object_ref::{Self, ObjectRef}; - use moveos_std::type_table; friend nft::nft; @@ -18,12 +17,11 @@ module nft::collection{ const ErrorCollectionNotExist: u64 = 2; const ErrorCollectionMaximumSupply: u64 = 3; - struct Collection has key{ + struct Collection has key{ name: String, uri: String, creator: address, supply: Supply, - extend: type_table::TypeTable } struct Supply has store{ @@ -31,10 +29,6 @@ module nft::collection{ maximum: Option, } - struct MutatorRef has key,store{ - collection: ObjectID, - } - struct CreateCollectionEvent{ objectID: ObjectID, name: String, @@ -44,14 +38,24 @@ module nft::collection{ description: String, } - public(friend) fun create_collection( + fun init(ctx: &mut Context){ + let collection_display_obj = display::new(ctx); + display::set(&mut collection_display_obj, string::utf8(b"name"), string::utf8(b"{ name }")); + display::set(&mut collection_display_obj, string::utf8(b"uri"), string::utf8(b"{ uri }")); + display::set(&mut collection_display_obj, string::utf8(b"description"), string::utf8(b"{ description }")); + display::set(&mut collection_display_obj, string::utf8(b"creator"), string::utf8(b"{ creator }")); + display::set(&mut collection_display_obj, string::utf8(b"supply"), string::utf8(b"{ supply }")); + object_ref::to_permanent(collection_display_obj); + } + + public fun create_collection( + ctx: &mut Context, name: String, uri: String, creator: address, description: String, max_supply: Option, - ctx: &mut Context - ):ObjectRef> { + ):ObjectRef { let collection = Collection { name, @@ -61,14 +65,13 @@ module nft::collection{ current: 0, maximum: max_supply, }, - extend: type_table::new(ctx) }; - let object_ref = context::new_object_with_owner( + let object_ref = context::new_object( ctx, - creator, collection ); + object_ref::transfer_extend(&mut object_ref, creator); event::emit( ctx, @@ -84,157 +87,44 @@ module nft::collection{ object_ref } - public fun generate_mutator_ref(collection: &ObjectRef>):MutatorRef{ - MutatorRef { - collection: object_ref::id(collection), - } - } - - public(friend) fun new_display(ctx: &mut Context):ObjectRef>>{ - display::new>(ctx) - } - - public fun destroy_mutator_ref(mutator_ref :MutatorRef):ObjectID{ - let MutatorRef { - collection, - } = mutator_ref; - collection - } - - public fun get_collection_id(mutator: &MutatorRef): ObjectID{ - mutator.collection - } - - - public(friend) fun increment_supply(mutator: &MutatorRef, ctx: &mut Context): Option{ - assert_collection_exist_of_id(mutator.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - collection_mut_ref.supply.current = collection_mut_ref.supply.current + 1; - if(option::is_some(&collection_mut_ref.supply.maximum)){ - assert!(collection_mut_ref.supply.current <= *option::borrow(&collection_mut_ref.supply.maximum), ErrorCollectionMaximumSupply); - option::some(collection_mut_ref.supply.current) + public(friend) fun increment_supply(collection: &mut Collection): Option{ + collection.supply.current = collection.supply.current + 1; + if(option::is_some(&collection.supply.maximum)){ + assert!(collection.supply.current <= *option::borrow(&collection.supply.maximum), ErrorCollectionMaximumSupply); + option::some(collection.supply.current) }else{ option::none() } } - public (friend) fun decrement_supply(mutator: &MutatorRef, ctx: &mut Context): Option{ - assert_collection_exist_of_id(mutator.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - collection_mut_ref.supply.current = collection_mut_ref.supply.current - 1; - if(option::is_some(&collection_mut_ref.supply.maximum)){ - option::some(collection_mut_ref.supply.current) + public(friend) fun decrement_supply(collection: &mut Collection): Option{ + collection.supply.current = collection.supply.current - 1; + if(option::is_some(&collection.supply.maximum)){ + option::some(collection.supply.current) }else{ option::none() } } - // assert - public fun assert_collection_exist_of_ref(collectionRef: &ObjectRef>){ - assert!( object_ref::exist_object(collectionRef), ErrorCollectionNotExist); - } - - public fun assert_collection_exist_of_id(collectionID: ObjectID, ctx: & Context){ - assert!( context::exist_object(ctx, collectionID), ErrorCollectionNotExist); - context::borrow_object>(ctx,collectionID); - } - - #[private_generics(V)] - public fun add_extend(mutator: &MutatorRef, val: V, ctx: &mut Context){ - add_extend_internal(mutator, val, ctx); - } - - #[private_generics(V)] - public fun borrow_extend(mutator: &MutatorRef, ctx: &mut Context):&V{ - borrow_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun borrow_mut_extend(mutator: &MutatorRef, ctx: &mut Context):&mut V{ - borrow_mut_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun remove_extend(mutator: &MutatorRef, ctx: &mut Context):V{ - remove_extend_internal(mutator, ctx) - } - - public fun contains_extend(mutator: &MutatorRef, ctx: &mut Context): bool{ - contains_extend_internal(mutator, ctx) - } - - - fun add_extend_internal(mutator: &MutatorRef,val: V,ctx: &mut Context){ - assert_collection_exist_of_id(mutator.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - type_table::add( &mut collection_mut_ref.extend, val); - } - - fun borrow_extend_internal(mutator: &MutatorRef, ctx: &mut Context):&V{ - assert_collection_exist_of_id(mutator.collection, ctx); - let collection_object_ref = context::borrow_object>(ctx, mutator.collection); - let collection_ref = object::borrow(collection_object_ref); - type_table::borrow(&collection_ref.extend) - } - - fun borrow_mut_extend_internal(mutator: &MutatorRef, ctx: &mut Context):&mut V{ - assert_collection_exist_of_id(mutator.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - type_table::borrow_mut(&mut collection_mut_ref.extend) - } - - fun remove_extend_internal(mutator: &MutatorRef, ctx: &mut Context):V{ - assert_collection_exist_of_id(mutator.collection, ctx); - let collection_object_mut_ref = context::borrow_object_mut>(ctx, mutator.collection); - let collection_mut_ref = object::borrow_mut(collection_object_mut_ref); - type_table::remove(&mut collection_mut_ref.extend) - } - - fun contains_extend_internal(mutator: &MutatorRef, ctx: &mut Context): bool{ - assert_collection_exist_of_id(mutator.collection, ctx); - let collection_object_ref = context::borrow_object>(ctx, mutator.collection); - let collection_ref = object::borrow(collection_object_ref); - type_table::contains(&collection_ref.extend) - } - // view - public fun get_collection_name(collectionID: ObjectID, ctx: &mut Context): String{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object>(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.name + public fun name(collection: &Collection): String{ + collection.name } - public fun get_collection_uri(collectionID: ObjectID, ctx: &mut Context): String{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object>(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.uri + public fun uri(collection: &Collection): String{ + collection.uri } - public fun get_collection_creator(collectionID: ObjectID, ctx: &mut Context): address{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object>(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.creator + public fun creator(collection: &Collection): address{ + collection.creator } - public fun get_collection_current_supply(collectionID: ObjectID, ctx: &mut Context): u64{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object>(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.supply.current + public fun current_supply(collection: &Collection): u64{ + collection.supply.current } - public fun get_collection_maximum_supply(collectionID: ObjectID, ctx: &mut Context): Option{ - assert_collection_exist_of_id(collectionID, ctx); - let collection_object_ref = context::borrow_object>(ctx, collectionID); - let collection_ref = object::borrow(collection_object_ref); - collection_ref.supply.maximum + public fun maximum_supply(collection: &Collection): Option{ + collection.supply.maximum } } diff --git a/examples/nft/sources/nft.move b/examples/nft/sources/nft.move index 110c11bb87..b86386eb62 100644 --- a/examples/nft/sources/nft.move +++ b/examples/nft/sources/nft.move @@ -2,286 +2,122 @@ // SPDX-License-Identifier: Apache-2.0 module nft::nft { - use std::option::Option; - use std::string::String; - use nft::collection::{Self, Collection}; - use rooch_framework::display::{Self, Display}; + use std::string::{Self, String}; + use nft::collection; + use rooch_framework::display; use moveos_std::object_ref::{Self, ObjectRef}; use moveos_std::context::{Self, Context}; - use moveos_std::type_table; - use moveos_std::object::{Self, ObjectID}; - use moveos_std::type_table::TypeTable; + use moveos_std::object::{ObjectID}; #[test_only] use std::option; #[test_only] - use std::string; - #[test_only] use rooch_framework::account; const ErrorNftNotExist: u64 = 1; const ErrorMutatorNotExist: u64 = 2; const ErrorBurnerNotExist: u64 = 3; - struct NFT has key,store { + struct NFT has key,store { name: String, uri: String, collection: ObjectID, creator: address, - extend: TypeTable - } - - struct MutatorRef has key,store { - nft: ObjectID, } - struct BurnerRef has key,store { - nft: ObjectID, + fun init(ctx: &mut Context){ + let nft_display_object = display::new(ctx); + display::set(&mut nft_display_object, string::utf8(b"name"), string::utf8(b"{ name }")); + display::set(&mut nft_display_object, string::utf8(b"uri"), string::utf8(b"{ uri }")); + object_ref::to_permanent(nft_display_object); } - #[private_generics(T)] - public fun create_collection( + /// Mint a new NFT, + public fun mint( + ctx: &mut Context, + collection_obj: &mut ObjectRef, name: String, uri: String, - creator: address, - description: String, - supply: Option, - ctx: &mut Context - ):(ObjectRef>,ObjectRef>>,ObjectRef>>) { - let collection_object_ref = collection::create_collection( + ): ObjectRef { + let collection_id = object_ref::id(collection_obj); + let collection = object_ref::borrow_mut(collection_obj); + collection::increment_supply(collection); + //NFT's creator should be the same as collection's creator? + let creator = collection::creator(collection); + let nft = NFT { name, uri, + collection: collection_id, creator, - description, - supply, - ctx - ); - let collection_display_object_ref = collection::new_display(ctx); - let nft_display_object_ref = display::new>(ctx); - - (collection_object_ref, collection_display_object_ref, nft_display_object_ref) - } - - #[private_generics(T)] - public fun mint( - name: String, - uri: String, - mutator_ref: &collection::MutatorRef, - creator: address, - ctx: &mut Context - ): ObjectRef> { - let nft = NFT { - name, - uri, - collection: collection::get_collection_id(mutator_ref), - creator, - extend: type_table::new(ctx) }; - - collection::increment_supply(mutator_ref, ctx); - - let object_ref = context::new_object_with_owner( + + let nft_obj = context::new_object( ctx, - creator, nft ); - - object_ref + nft_obj } - public fun burn ( - burn_ref: &BurnerRef, - mutator_ref: & collection::MutatorRef, - ctx: &mut Context + public fun burn ( + collection_obj: &mut ObjectRef, + nft_object: ObjectRef, ) { - assert_nft_exist_of_id(burn_ref.nft, ctx); - collection::decrement_supply(mutator_ref, ctx); + let collection = object_ref::borrow_mut(collection_obj); + collection::decrement_supply(collection); let ( - _, - _, NFT { name:_, uri:_, collection:_, creator:_, - extend } - ) = context::remove_object>(ctx, burn_ref.nft); - if(type_table::contains>( &extend )){ - type_table::remove>( &mut extend); - }; - type_table::destroy_empty(extend) - } - - public fun generate_mutator_ref(nft_object_ref: &ObjectRef>):MutatorRef{ - MutatorRef { - nft: object_ref::id(nft_object_ref), - } - } - - public fun destroy_mutator_ref(mutator_ref :MutatorRef):ObjectID{ - let MutatorRef { - nft - } = mutator_ref ; - nft - } - - public fun generate_burner_ref(nft_object_ref: &ObjectRef>):BurnerRef{ - BurnerRef { - nft: object_ref::id(nft_object_ref), - } - } - - public fun destroy_burner_ref(burner_ref :BurnerRef):ObjectID{ - let BurnerRef { - nft - } = burner_ref; - nft - } - - // assert - public fun assert_nft_exist_of_id(objectId: ObjectID, ctx: &Context) { - assert!(context::exist_object(ctx, objectId), ErrorNftNotExist); - context::borrow_object>(ctx, objectId); - } - - public fun assert_nft_exist_of_ref(nft_object_ref: &ObjectRef>) { - assert!(object_ref::exist_object(nft_object_ref), ErrorNftNotExist); - } - - #[private_generics(V)] - public fun add_extend(mutator: &MutatorRef, val: V, ctx: &mut Context){ - add_extend_internal(mutator, val, ctx); - } - - public fun borrow_extend(mutator: &MutatorRef, ctx: &mut Context):&V{ - borrow_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun borrow_mut_extend(mutator: &MutatorRef, ctx: &mut Context):&mut V{ - borrow_mut_extend_internal(mutator, ctx) - } - - #[private_generics(V)] - public fun remove_extend(mutator: &MutatorRef, ctx: &mut Context):V{ - remove_extend_internal(mutator, ctx) - } - - public fun contains_extend(mutator: &MutatorRef, ctx: &mut Context): bool{ - contains_extend_internal(mutator, ctx) - } - - fun add_extend_internal(mutator: &MutatorRef,val: V,ctx: &mut Context) { - let nft_object_mut_ref = context::borrow_object_mut>(ctx, mutator.nft); - let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); - type_table::add( &mut nft_mut_ref.extend, val); - } - - fun borrow_extend_internal(mutator: &MutatorRef,ctx: &Context): &V { - let nft_object_ref = context::borrow_object>(ctx, mutator.nft); - let nft_mut_ref = object::borrow(nft_object_ref); - type_table::borrow(&nft_mut_ref.extend) - } - - fun borrow_mut_extend_internal(mutator: &MutatorRef,ctx: &mut Context): &mut V { - let nft_object_mut_ref = context::borrow_object_mut>(ctx, mutator.nft); - let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); - type_table::borrow_mut(&mut nft_mut_ref.extend) - } - - fun remove_extend_internal(mutator: &MutatorRef,ctx: &mut Context):V { - let nft_object_mut_ref = context::borrow_object_mut>(ctx, mutator.nft); - let nft_mut_ref = object::borrow_mut(nft_object_mut_ref); - type_table::remove(&mut nft_mut_ref.extend) - } - - fun contains_extend_internal(mutator: &MutatorRef,ctx: &Context): bool { - let nft_object_ref = context::borrow_object>(ctx, mutator.nft); - let nft_mut_ref = object::borrow(nft_object_ref); - type_table::contains(&nft_mut_ref.extend) + ) = object_ref::remove(nft_object); } // view - public fun get_name(objectId: ObjectID, ctx: &Context): String { - assert_nft_exist_of_id(objectId, ctx); - let nft_object_ref = context::borrow_object>(ctx, objectId); - let nft = object::borrow(nft_object_ref); + public fun name(nft: &NFT): String { nft.name } - public fun get_uri(objectId: ObjectID, ctx: &Context): String { - assert_nft_exist_of_id(objectId, ctx); - let nft_object_ref = context::borrow_object>(ctx, objectId); - let nft = object::borrow(nft_object_ref); + public fun uri(nft: &NFT): String { nft.uri } - public fun get_collection(objectId: ObjectID, ctx: &Context): ObjectID { - assert_nft_exist_of_id(objectId, ctx); - let nft_object_ref = context::borrow_object>(ctx, objectId); - let nft = object::borrow(nft_object_ref); + public fun collection(nft: &NFT): ObjectID { nft.collection } - public fun get_creator(objectId: ObjectID, ctx: &Context): address { - assert_nft_exist_of_id(objectId, ctx); - let nft_object_ref = context::borrow_object>(ctx, objectId); - let nft = object::borrow(nft_object_ref); + public fun creator(nft: &NFT): address { nft.creator } - #[test_only] - struct Test has key {} - #[test(sender = @nft)] public fun test_create_nft (sender: address){ let storage_context = context::new_test_context(sender); let ctx = &mut storage_context; account::create_account_for_test(ctx, sender); - let ( - collection_object_ref, - collection_display_object_ref, - nft_display_object_ref - ) = create_collection( - string::utf8(b"name"), - string::utf8(b"uri"), + let collection_obj = collection::create_collection( + ctx, + string::utf8(b"test_collection_name1"), + string::utf8(b"test_collection_uri1"), sender, - string::utf8(b"description"), + string::utf8(b"test_collection_description1"), option::none(), - ctx ); - let collection_mutator_ref = collection::generate_mutator_ref(&collection_object_ref); - - display::set(&mut collection_display_object_ref, string::utf8(b"name"), string::utf8(b"{ name }")); - display::set(&mut collection_display_object_ref, string::utf8(b"uri"), string::utf8(b"{ uri }")); - display::set(&mut collection_display_object_ref, string::utf8(b"description"), string::utf8(b"{ description }")); - display::set(&mut collection_display_object_ref, string::utf8(b"creator"), string::utf8(b"{ creator }")); - display::set(&mut collection_display_object_ref, string::utf8(b"supply"), string::utf8(b"{ supply }")); - - display::set(&mut nft_display_object_ref, string::utf8(b"name"), string::utf8(b"{ name }")); - display::set(&mut nft_display_object_ref, string::utf8(b"uri"), string::utf8(b"{ uri }")); - - let nft_object_ref = mint( - string::utf8(b"name"), - string::utf8(b"uri"), - &collection_mutator_ref, - sender, - ctx + + let nft_obj = mint( + ctx, + &mut collection_obj, + string::utf8(b"test_nft_1"), + string::utf8(b"test_nft_uri"), ); + object_ref::transfer(&mut nft_obj, sender); - let nft_mutaor_ref = generate_mutator_ref(&nft_object_ref); - - let burner_ref = generate_burner_ref(&nft_object_ref); - - burn(&burner_ref, &collection_mutator_ref, ctx); - - collection::destroy_mutator_ref(collection_mutator_ref); + burn(&mut collection_obj, nft_obj); - destroy_mutator_ref(nft_mutaor_ref); - destroy_burner_ref(burner_ref); + object_ref::to_permanent(collection_obj); context::drop_test_context(storage_context); } From 6b9e03cc706d81fa32741e96d40c4bd7b7494db3 Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 18:49:32 +0800 Subject: [PATCH 12/18] [Examples] Add entry function to nft example --- examples/nft/sources/collection.move | 12 ++++++------ examples/nft/sources/nft.move | 13 +++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/examples/nft/sources/collection.move b/examples/nft/sources/collection.move index b0dc8fe2ce..3abb5ace56 100644 --- a/examples/nft/sources/collection.move +++ b/examples/nft/sources/collection.move @@ -48,6 +48,7 @@ module nft::collection{ object_ref::to_permanent(collection_display_obj); } + /// Create a new collection Object public fun create_collection( ctx: &mut Context, name: String, @@ -55,7 +56,7 @@ module nft::collection{ creator: address, description: String, max_supply: Option, - ):ObjectRef { + ) : ObjectRef { let collection = Collection { name, @@ -67,16 +68,14 @@ module nft::collection{ }, }; - let object_ref = context::new_object( + let collection_obj = context::new_object( ctx, collection ); - object_ref::transfer_extend(&mut object_ref, creator); - event::emit( ctx, CreateCollectionEvent { - objectID: object_ref::id(&object_ref), + objectID: object_ref::id(&collection_obj), name, uri, creator, @@ -84,7 +83,8 @@ module nft::collection{ description, } ); - object_ref + object_ref::transfer_extend(&mut collection_obj, creator); + collection_obj } public(friend) fun increment_supply(collection: &mut Collection): Option{ diff --git a/examples/nft/sources/nft.move b/examples/nft/sources/nft.move index b86386eb62..0847a73bb3 100644 --- a/examples/nft/sources/nft.move +++ b/examples/nft/sources/nft.move @@ -91,6 +91,19 @@ module nft::nft { nft.creator } + /// Mint a new NFT and transfer it to sender + /// Because only the creator of the collection can get `&mut ObjectRef` + /// So, only the creator of the collection can mint a new NFT + /// If we want to allow other people to mint NFT, we need to make the `ObjectRef` to shared + entry fun mint_entry(ctx: &mut Context, collection_obj: &mut ObjectRef, name: String, uri: String) { + let sender = context::sender(ctx); + let nft_obj = mint(ctx, collection_obj, name, uri); + object_ref::transfer(&mut nft_obj, sender); + //Because the NFT becomes permanent Object here, we can not to burn it. + //Maybe we need to design a NFTGallery to store all the NFTs of user. + object_ref::to_permanent(nft_obj); + } + #[test(sender = @nft)] public fun test_create_nft (sender: address){ let storage_context = context::new_test_context(sender); From f186faf8d8a0d8d6879aabc0e639139299108925 Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 21:03:41 +0800 Subject: [PATCH 13/18] [examples] complex_struct and entry_function_arguments example --- .../sources/complex_struct.move | 24 ++++++++++--------- .../sources/entry_function.move | 18 ++++++++++++++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/examples/complex_struct/sources/complex_struct.move b/examples/complex_struct/sources/complex_struct.move index 3388c89c06..9ad693016d 100644 --- a/examples/complex_struct/sources/complex_struct.move +++ b/examples/complex_struct/sources/complex_struct.move @@ -5,9 +5,10 @@ module rooch_examples::complex_struct { use moveos_std::context::{Self, Context}; use moveos_std::account_storage; - use moveos_std::object_ref; + use moveos_std::object_ref::{Self, ObjectRef}; use moveos_std::object::ObjectID; use moveos_std::bcs; + use moveos_std::signer; use std::vector; struct SimpleStruct has store, copy, drop { @@ -104,20 +105,21 @@ module rooch_examples::complex_struct { } //init when module publish - fun init(ctx: &mut Context, sender: signer) { - + fun init(ctx: &mut Context) { + let module_signer = signer::module_signer(); let object_id = context::fresh_object_id(ctx); let s = new_complex_struct(object_id); - let complex_object_ref = { - context::new_object(ctx, s) - }; - let complex_object_id = object_ref::id(&complex_object_ref); - - let s2 = new_complex_struct(complex_object_id); - account_storage::global_move_to(ctx, &sender, s2); + let complex_object = context::new_object(ctx, s); + object_ref::to_permanent(complex_object); + let s2 = new_complex_struct(object_id); + account_storage::global_move_to(ctx, &module_signer, s2); } - public fun value(ctx: & Context): &ComplexStruct { + public fun value(ctx: &Context): &ComplexStruct { account_storage::global_borrow(ctx,@rooch_examples) } + + public fun value_of_object(obj: &ObjectRef) : &ComplexStruct { + object_ref::borrow(obj) + } } diff --git a/examples/entry_function_arguments/sources/entry_function.move b/examples/entry_function_arguments/sources/entry_function.move index 37ff3ee078..24bc252002 100644 --- a/examples/entry_function_arguments/sources/entry_function.move +++ b/examples/entry_function_arguments/sources/entry_function.move @@ -3,6 +3,7 @@ module rooch_examples::entry_function { use moveos_std::event; + use moveos_std::object_ref::{Self, ObjectRef}; use moveos_std::object::ObjectID; use moveos_std::context::Context; @@ -95,4 +96,21 @@ module rooch_examples::entry_function { event::emit(ctx, U8Event { value: value1 }); event::emit(ctx, VecObjectIDEvent { value: value2 }); } + + struct TestStruct has key{} + + struct ObjectEvent{ + is_mut: bool, + value: ObjectID, + } + + public entry fun emit_object(ctx: &mut Context, obj: &ObjectRef) { + let object_id = object_ref::id(obj); + event::emit(ctx, ObjectEvent { is_mut: false, value: object_id }); + } + + public entry fun emit_object_mut(ctx: &mut Context, obj: &mut ObjectRef) { + let object_id = object_ref::id(obj); + event::emit(ctx, ObjectEvent { is_mut: true, value: object_id }); + } } From 3897872f54d8d1dc99e4aeec850985a6f18d084b Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 21:04:03 +0800 Subject: [PATCH 14/18] [examples] blog example --- examples/blog/sources/article.move | 81 +++++++++---------- .../sources/article_add_comment_logic.move | 13 ++- examples/blog/sources/article_aggregate.move | 48 +++++------ .../blog/sources/article_create_logic.move | 12 +-- .../blog/sources/article_delete_logic.move | 10 +-- .../sources/article_remove_comment_logic.move | 13 +-- .../sources/article_update_comment_logic.move | 13 +-- .../blog/sources/article_update_logic.move | 16 ++-- examples/blog/sources/blog.move | 33 +++----- .../blog/sources/blog_add_article_logic.move | 12 +-- examples/blog/sources/blog_aggregate.move | 15 ++-- examples/blog/sources/blog_create_logic.move | 8 +- examples/blog/sources/blog_created.move | 5 -- .../sources/blog_remove_article_logic.move | 14 ++-- examples/blog/sources/blog_update_logic.move | 5 -- examples/blog/sources/blog_updated.move | 6 +- 16 files changed, 124 insertions(+), 180 deletions(-) diff --git a/examples/blog/sources/article.move b/examples/blog/sources/article.move index 05a17f8c7e..276f19c288 100644 --- a/examples/blog/sources/article.move +++ b/examples/blog/sources/article.move @@ -59,8 +59,9 @@ module rooch_examples::article { } public(friend) fun next_comment_seq_id(article_obj: &mut ObjectRef
): u64 { - object_ref::borrow_mut(article_obj).comment_seq_id_generator.sequence = object_ref::borrow(article_obj).comment_seq_id_generator.sequence + 1; - object_ref::borrow(article_obj).comment_seq_id_generator.sequence + let article = object_ref::borrow_mut(article_obj); + article.comment_seq_id_generator.sequence = article.comment_seq_id_generator.sequence + 1; + article.comment_seq_id_generator.sequence } /// get object id @@ -68,32 +69,33 @@ module rooch_examples::article { object_ref::id(article_obj) } - public fun version(article_obj: &ObjectRef
): u64 { - object_ref::borrow(article_obj).version + public fun version(article: &Article): u64 { + article.version } - public fun title(article_obj: &ObjectRef
): String { - object_ref::borrow(article_obj).title + public fun title(article: &Article): String { + article.title } - public(friend) fun set_title(article_obj: &mut ObjectRef
, title: String) { + public(friend) fun set_title(article: &mut Article, title: String) { assert!(std::string::length(&title) <= 200, ErrorDataTooLong); - object_ref::borrow_mut(article_obj).title = title; + article.title = title; } - public fun body(article_obj: &ObjectRef
): String { - object_ref::borrow(article_obj).body + public fun body(article: &Article): String { + article.body } - public(friend) fun set_body(article_obj: &mut ObjectRef
, body: String) { + public(friend) fun set_body(article: &mut Article, body: String) { assert!(std::string::length(&body) <= 2000, ErrorDataTooLong); - object_ref::borrow_mut(article_obj).body = body; + article.body = body; } public(friend) fun add_comment(ctx: &mut Context, article_obj: &mut ObjectRef
, comment: Comment) { + let article = object_ref::borrow_mut(article_obj); let comment_seq_id = comment::comment_seq_id(&comment); - assert!(!table::contains(&object_ref::borrow_mut(article_obj).comments, comment_seq_id), ErrorIdAlreadyExists); - table::add(&mut object_ref::borrow_mut(article_obj).comments, comment_seq_id, comment); + assert!(!table::contains(&article.comments, comment_seq_id), ErrorIdAlreadyExists); + table::add(&mut article.comments, comment_seq_id, comment); event::emit(ctx, CommentTableItemAdded { article_id: id(article_obj), comment_seq_id, @@ -101,8 +103,9 @@ module rooch_examples::article { } public(friend) fun remove_comment(article_obj: &mut ObjectRef
, comment_seq_id: u64) { - assert!(table::contains(&object_ref::borrow_mut(article_obj).comments, comment_seq_id), ErrorIdNotFound); - let comment = table::remove(&mut object_ref::borrow_mut(article_obj).comments, comment_seq_id); + let article = object_ref::borrow_mut(article_obj); + assert!(table::contains(&article.comments, comment_seq_id), ErrorIdNotFound); + let comment = table::remove(&mut article.comments, comment_seq_id); comment::drop_comment(comment); } @@ -170,9 +173,10 @@ module rooch_examples::article { body: String, owner: address, ): CommentUpdated { + let article = object_ref::borrow(article_obj); CommentUpdated { id: id(article_obj), - version: version(article_obj), + version: version(article), comment_seq_id, commenter, body, @@ -198,9 +202,10 @@ module rooch_examples::article { article_obj: &ObjectRef
, comment_seq_id: u64, ): CommentRemoved { + let article = object_ref::borrow(article_obj); CommentRemoved { id: id(article_obj), - version: version(article_obj), + version: version(article), comment_seq_id, } } @@ -241,9 +246,10 @@ module rooch_examples::article { body: String, owner: address, ): CommentAdded { + let article = object_ref::borrow(article_obj); CommentAdded { id: id(article_obj), - version: version(article_obj), + version: version(article), comment_seq_id, commenter, body, @@ -308,9 +314,10 @@ module rooch_examples::article { title: String, body: String, ): ArticleUpdated { + let article = object_ref::borrow(article_obj); ArticleUpdated { id: id(article_obj), - version: version(article_obj), + version: version(article), title, body, } @@ -328,9 +335,10 @@ module rooch_examples::article { public(friend) fun new_article_deleted( article_obj: &ObjectRef
, ): ArticleDeleted { + let article = object_ref::borrow(article_obj); ArticleDeleted { id: id(article_obj), - version: version(article_obj), + version: version(article), } } @@ -353,34 +361,21 @@ module rooch_examples::article { article_obj } - public(friend) fun update_version_and_add(ctx: &mut Context, article_obj: ObjectRef
) { - object_ref::borrow_mut(&mut article_obj).version = object_ref::borrow( &mut article_obj).version + 1; - //assert!(object_ref::borrow(&article_obj).version != 0, ErrorInappropriateVersion); - private_add_article(ctx, article_obj); - } - - public(friend) fun remove_article(ctx: &mut Context, obj_id: ObjectID): Article { - let (_id,_owner,article) = context::remove_object
(ctx, obj_id); - article - } - - public(friend) fun add_article(ctx: &mut Context, article_obj: ObjectRef
) { - assert!(object_ref::borrow(&article_obj).version == 0, ErrorInappropriateVersion); - private_add_article(ctx, article_obj); + public(friend) fun update_version(article_obj: &mut ObjectRef
) { + let article = object_ref::borrow_mut(article_obj); + article.version = article.version + 1; } - fun private_add_article(_ctx: &mut Context, article_obj: ObjectRef
) { - assert!(std::string::length(&object_ref::borrow(&article_obj).title) <= 200, ErrorDataTooLong); - assert!(std::string::length(&object_ref::borrow(&article_obj).body) <= 2000, ErrorDataTooLong); + public(friend) fun remove_article(article_obj: ObjectRef
): Article { + object_ref::remove(article_obj) } - public fun get_article(ctx: &mut Context, obj_id: ObjectID): ObjectRef
{ - let object_ref = context::borrow_object_mut
(ctx, obj_id); - object_ref::new(object_ref) + public fun get_article_mut(ctx: &mut Context, obj_id: ObjectID): &mut ObjectRef
{ + context::borrow_object_mut_extend
(ctx, obj_id) } - public fun return_article(ctx: &mut Context, article_obj: ObjectRef
) { - private_add_article(ctx, article_obj); + public fun get_article(ctx: &mut Context, obj_id: ObjectID): &ObjectRef
{ + context::borrow_object
(ctx, obj_id) } public(friend) fun drop_article(article_obj: ObjectRef
) { diff --git a/examples/blog/sources/article_add_comment_logic.move b/examples/blog/sources/article_add_comment_logic.move index 441a4364a0..3acffabd73 100644 --- a/examples/blog/sources/article_add_comment_logic.move +++ b/examples/blog/sources/article_add_comment_logic.move @@ -12,13 +12,11 @@ module rooch_examples::article_add_comment_logic { friend rooch_examples::article_aggregate; public(friend) fun verify( - ctx: &mut Context, account: &signer, commenter: String, body: String, article_obj: &ObjectRef
, ): article::CommentAdded { - let _ = ctx; let _ = account; let comment_seq_id = article::current_comment_seq_id(article_obj) + 1; article::new_comment_added( @@ -34,13 +32,13 @@ module rooch_examples::article_add_comment_logic { ctx: &mut Context, _account: &signer, comment_added: &article::CommentAdded, - article_obj: ObjectRef
, - ): ObjectRef
{ - let comment_seq_id = article::next_comment_seq_id(&mut article_obj); + article_obj: &mut ObjectRef
, + ) { + let comment_seq_id = article::next_comment_seq_id(article_obj); let commenter = comment_added::commenter(comment_added); let body = comment_added::body(comment_added); let owner = comment_added::owner(comment_added); - let id = article::id(&article_obj); + let id = article::id(article_obj); let _ = ctx; let _ = id; let comment = comment::new_comment( @@ -49,8 +47,7 @@ module rooch_examples::article_add_comment_logic { body, owner, ); - article::add_comment(ctx, &mut article_obj, comment); - article_obj + article::add_comment(ctx, article_obj, comment); } } diff --git a/examples/blog/sources/article_aggregate.move b/examples/blog/sources/article_aggregate.move index e62707e31c..3fa28f09f8 100644 --- a/examples/blog/sources/article_aggregate.move +++ b/examples/blog/sources/article_aggregate.move @@ -27,23 +27,21 @@ module rooch_examples::article_aggregate { body: String, owner: address, ) { - let article_obj = article::get_article(ctx, id); + let article_obj = article::get_article_mut(ctx, id); let comment_updated = article_update_comment_logic::verify( - ctx, account, comment_seq_id, commenter, body, owner, - &article_obj, + article_obj, ); - let updated_article_obj = article_update_comment_logic::mutate( - ctx, + article_update_comment_logic::mutate( account, &comment_updated, article_obj, ); - article::update_version_and_add(ctx, updated_article_obj); + article::update_version(article_obj); article::emit_comment_updated(ctx, comment_updated); } @@ -53,20 +51,18 @@ module rooch_examples::article_aggregate { id: ObjectID, comment_seq_id: u64, ) { - let article_obj = article::get_article(ctx, id); + let article_obj = article::get_article_mut(ctx, id); let comment_removed = article_remove_comment_logic::verify( - ctx, account, comment_seq_id, - &article_obj, + article_obj, ); - let updated_article_obj = article_remove_comment_logic::mutate( - ctx, + article_remove_comment_logic::mutate( account, &comment_removed, article_obj, ); - article::update_version_and_add(ctx, updated_article_obj); + article::update_version(article_obj); article::emit_comment_removed(ctx, comment_removed); } @@ -77,21 +73,21 @@ module rooch_examples::article_aggregate { commenter: String, body: String, ) { - let article_obj = article::get_article(ctx, id); + let article_obj = article::get_article_mut(ctx, id); let comment_added = article_add_comment_logic::verify( ctx, account, commenter, body, - &article_obj, + article_obj, ); - let updated_article_obj = article_add_comment_logic::mutate( + article_add_comment_logic::mutate( ctx, account, &comment_added, article_obj, ); - article::update_version_and_add(ctx, updated_article_obj); + article::update_version(article_obj); article::emit_comment_added(ctx, comment_added); } @@ -107,13 +103,12 @@ module rooch_examples::article_aggregate { title, body, ); - let article_obj = article_create_logic::mutate( + let article_id = article_create_logic::mutate( ctx, account, &article_created, ); - article::set_article_created_id(&mut article_created, article::id(&article_obj)); - article::add_article(ctx, article_obj); + article::set_article_created_id(&mut article_created, article_id); article::emit_article_created(ctx, article_created); } @@ -124,21 +119,19 @@ module rooch_examples::article_aggregate { title: String, body: String, ) { - let article_obj = article::get_article(ctx, id); + let article_obj = article::get_article_mut(ctx, id); let article_updated = article_update_logic::verify( - ctx, account, title, body, - &article_obj, + article_obj, ); - let updated_article_obj = article_update_logic::mutate( - ctx, + article_update_logic::mutate( account, &article_updated, article_obj, ); - article::update_version_and_add(ctx, updated_article_obj); + article::update_version(article_obj); article::emit_article_updated(ctx, article_updated); } @@ -149,15 +142,14 @@ module rooch_examples::article_aggregate { ) { let article_obj = article::get_article(ctx, id); let article_deleted = article_delete_logic::verify( - ctx, account, - &article_obj, + article_obj, ); let updated_article_obj = article_delete_logic::mutate( ctx, account, &article_deleted, - article_obj, + id, ); article::drop_article(updated_article_obj); article::emit_article_deleted(ctx, article_deleted); diff --git a/examples/blog/sources/article_create_logic.move b/examples/blog/sources/article_create_logic.move index c5f2eb8680..0f33a6d003 100644 --- a/examples/blog/sources/article_create_logic.move +++ b/examples/blog/sources/article_create_logic.move @@ -2,8 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 module rooch_examples::article_create_logic { - use moveos_std::object_ref::ObjectRef; use moveos_std::context::Context; + use moveos_std::object_ref; + use moveos_std::object::ObjectID; use rooch_examples::article::{Self, Article}; use rooch_examples::article_created; use std::string::String; @@ -29,7 +30,7 @@ module rooch_examples::article_create_logic { ctx: &mut Context, _account: &signer, article_created: &article::ArticleCreated, - ): ObjectRef
{ + ) : ObjectID { let title = article_created::title(article_created); let body = article_created::body(article_created); let article_obj = article::create_article( @@ -37,10 +38,9 @@ module rooch_examples::article_create_logic { title, body, ); - // /////////////////////////// - blog_aggregate::add_article(ctx, article::id(&article_obj)); - // /////////////////////////// - article_obj + let article_id = object_ref::id(&article_obj); + blog_aggregate::add_article(ctx, article_obj); + article_id } } diff --git a/examples/blog/sources/article_delete_logic.move b/examples/blog/sources/article_delete_logic.move index 346a05513f..108ed68065 100644 --- a/examples/blog/sources/article_delete_logic.move +++ b/examples/blog/sources/article_delete_logic.move @@ -4,17 +4,16 @@ module rooch_examples::article_delete_logic { use moveos_std::object_ref::ObjectRef; use moveos_std::context::Context; + use moveos_std::object::ObjectID; use rooch_examples::article::{Self, Article}; use rooch_examples::blog_aggregate; friend rooch_examples::article_aggregate; public(friend) fun verify( - ctx: &mut Context, account: &signer, article_obj: &ObjectRef
, ): article::ArticleDeleted { - let _ = ctx; let _ = account; article::new_article_deleted( article_obj, @@ -25,11 +24,10 @@ module rooch_examples::article_delete_logic { ctx: &mut Context, _account: &signer, article_deleted: &article::ArticleDeleted, - article_obj: ObjectRef
, - ): ObjectRef
{ + article_id: ObjectID, + ) : ObjectRef
{ let _ = article_deleted; - blog_aggregate::remove_article(ctx, article::id(&article_obj)); - article_obj + blog_aggregate::remove_article(ctx, article_id) } } diff --git a/examples/blog/sources/article_remove_comment_logic.move b/examples/blog/sources/article_remove_comment_logic.move index 1119981beb..e1681fcfcd 100644 --- a/examples/blog/sources/article_remove_comment_logic.move +++ b/examples/blog/sources/article_remove_comment_logic.move @@ -13,12 +13,10 @@ module rooch_examples::article_remove_comment_logic { const ErrorNotOwnerAccount: u64 = 113; public(friend) fun verify( - ctx: &mut Context, account: &signer, comment_seq_id: u64, article_obj: &ObjectRef
, ): article::CommentRemoved { - let _ = ctx; let comment = article::borrow_comment(article_obj, comment_seq_id); assert!(std::signer::address_of(account) == comment::owner(comment), ErrorNotOwnerAccount); article::new_comment_removed( @@ -28,17 +26,14 @@ module rooch_examples::article_remove_comment_logic { } public(friend) fun mutate( - ctx: &mut Context, _account: &signer, comment_removed: &article::CommentRemoved, - article_obj: ObjectRef
, - ): ObjectRef
{ + article_obj: &mut ObjectRef
, + ) { let comment_seq_id = comment_removed::comment_seq_id(comment_removed); - let id = article::id(&article_obj); - let _ = ctx; + let id = article::id(article_obj); let _ = id; - article::remove_comment(&mut article_obj, comment_seq_id); - article_obj + article::remove_comment(article_obj, comment_seq_id); } } diff --git a/examples/blog/sources/article_update_comment_logic.move b/examples/blog/sources/article_update_comment_logic.move index 2ddf50ce6d..87085f9c18 100644 --- a/examples/blog/sources/article_update_comment_logic.move +++ b/examples/blog/sources/article_update_comment_logic.move @@ -14,7 +14,6 @@ module rooch_examples::article_update_comment_logic { const ErrorNotOwnerAccount: u64 = 113; public(friend) fun verify( - ctx: &mut Context, account: &signer, comment_seq_id: u64, commenter: String, @@ -22,7 +21,6 @@ module rooch_examples::article_update_comment_logic { owner: address, article_obj: &ObjectRef
, ): article::CommentUpdated { - let _ = ctx; let comment = article::borrow_comment(article_obj, comment_seq_id); assert!(std::signer::address_of(account) == comment::owner(comment), ErrorNotOwnerAccount); article::new_comment_updated( @@ -35,23 +33,20 @@ module rooch_examples::article_update_comment_logic { } public(friend) fun mutate( - ctx: &mut Context, _account: &signer, comment_updated: &article::CommentUpdated, - article_obj: ObjectRef
, - ): ObjectRef
{ + article_obj: &mut ObjectRef
, + ) { let comment_seq_id = comment_updated::comment_seq_id(comment_updated); let commenter = comment_updated::commenter(comment_updated); let body = comment_updated::body(comment_updated); let owner = comment_updated::owner(comment_updated); - let id = article::id(&article_obj); - let _ = ctx; + let id = article::id(article_obj); let _ = id; - let comment = article::borrow_mut_comment(&mut article_obj, comment_seq_id); + let comment = article::borrow_mut_comment(article_obj, comment_seq_id); comment::set_commenter(comment, commenter); comment::set_body(comment, body); comment::set_owner(comment, owner); - article_obj } } diff --git a/examples/blog/sources/article_update_logic.move b/examples/blog/sources/article_update_logic.move index 2de4aa906f..e1c32932f5 100644 --- a/examples/blog/sources/article_update_logic.move +++ b/examples/blog/sources/article_update_logic.move @@ -14,13 +14,11 @@ module rooch_examples::article_update_logic { const ErrorNotOwnerAccount: u64 = 113; public(friend) fun verify( - ctx: &mut Context, account: &signer, title: String, body: String, article_obj: &ObjectRef
, ): article::ArticleUpdated { - let _ = ctx; assert!(signer::address_of(account) == object_ref::owner(article_obj), ErrorNotOwnerAccount); article::new_article_updated( article_obj, @@ -30,19 +28,17 @@ module rooch_examples::article_update_logic { } public(friend) fun mutate( - ctx: &mut Context, _account: &signer, article_updated: &article::ArticleUpdated, - article_obj: ObjectRef
, - ): ObjectRef
{ + article_obj: &mut ObjectRef
, + ) { let title = article_updated::title(article_updated); let body = article_updated::body(article_updated); - let id = article::id(&article_obj); - let _ = ctx; + let id = article::id(article_obj); let _ = id; - article::set_title(&mut article_obj, title); - article::set_body(&mut article_obj, body); - article_obj + let article = object_ref::borrow_mut(article_obj); + article::set_title(article, title); + article::set_body(article, body); } } diff --git a/examples/blog/sources/blog.move b/examples/blog/sources/blog.move index 81984ca3c6..fd9a33d175 100644 --- a/examples/blog/sources/blog.move +++ b/examples/blog/sources/blog.move @@ -10,10 +10,14 @@ module rooch_examples::blog { use moveos_std::account_storage; use moveos_std::event; use moveos_std::object::ObjectID; + use moveos_std::object_ref::ObjectRef; use moveos_std::context::Context; + use moveos_std::table::{Self, Table}; use std::error; use std::signer; use std::string::String; + use rooch_examples::article::Article; + friend rooch_examples::blog_add_article_logic; friend rooch_examples::blog_remove_article_logic; friend rooch_examples::blog_create_logic; @@ -28,7 +32,7 @@ module rooch_examples::blog { struct Blog has key, store { version: u64, name: String, - articles: vector, + articles: Table>, } public fun version(blog: &Blog): u64 { @@ -44,17 +48,17 @@ module rooch_examples::blog { blog.name = name; } - public fun articles(blog: &Blog): vector { - blog.articles + public fun articles(blog: &Blog): &Table> { + &blog.articles } - public(friend) fun set_articles(blog: &mut Blog, articles: vector) { - blog.articles = articles; + public fun articles_mut(blog: &mut Blog): &mut Table> { + &mut blog.articles } public(friend) fun new_blog( name: String, - articles: vector, + articles: Table>, ): Blog { assert!(std::string::length(&name) <= 200, ErrorDataTooLong); Blog { @@ -104,50 +108,36 @@ module rooch_examples::blog { struct BlogCreated has key { name: String, - articles: vector, } public fun blog_created_name(blog_created: &BlogCreated): String { blog_created.name } - public fun blog_created_articles(blog_created: &BlogCreated): vector { - blog_created.articles - } - public(friend) fun new_blog_created( name: String, - articles: vector, ): BlogCreated { BlogCreated { name, - articles, } } struct BlogUpdated has key { version: u64, name: String, - articles: vector, } public fun blog_updated_name(blog_updated: &BlogUpdated): String { blog_updated.name } - public fun blog_updated_articles(blog_updated: &BlogUpdated): vector { - blog_updated.articles - } - public(friend) fun new_blog_updated( blog: &Blog, name: String, - articles: vector, ): BlogUpdated { BlogUpdated { version: version(blog), name, - articles, } } @@ -189,8 +179,9 @@ module rooch_examples::blog { let Blog { version: _version, name: _name, - articles: _articles, + articles, } = blog; + table::destroy_empty(articles); } public(friend) fun borrow_mut_blog(ctx: &mut Context): &mut Blog { diff --git a/examples/blog/sources/blog_add_article_logic.move b/examples/blog/sources/blog_add_article_logic.move index 39a544c6b8..6576a4a011 100644 --- a/examples/blog/sources/blog_add_article_logic.move +++ b/examples/blog/sources/blog_add_article_logic.move @@ -2,11 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 module rooch_examples::blog_add_article_logic { - use std::vector; + use moveos_std::object_ref::ObjectRef; use moveos_std::object::ObjectID; + use moveos_std::table; use rooch_examples::article_added_to_blog; use rooch_examples::blog; + use rooch_examples::article::Article; friend rooch_examples::blog_aggregate; @@ -22,13 +24,11 @@ module rooch_examples::blog_add_article_logic { public(friend) fun mutate( article_added_to_blog: &blog::ArticleAddedToBlog, + article_obj: ObjectRef
, blog: &mut blog::Blog, ) { let article_id = article_added_to_blog::article_id(article_added_to_blog); - let articles = blog::articles(blog); - if (!vector::contains(&articles, &article_id)) { - vector::push_back(&mut articles, article_id); - blog::set_articles(blog, articles); - }; + let articles = blog::articles_mut(blog); + table::add(articles, article_id, article_obj); } } diff --git a/examples/blog/sources/blog_aggregate.move b/examples/blog/sources/blog_aggregate.move index 13ca9fe1e0..7d40d44ec4 100644 --- a/examples/blog/sources/blog_aggregate.move +++ b/examples/blog/sources/blog_aggregate.move @@ -9,12 +9,14 @@ module rooch_examples::blog_aggregate { use moveos_std::object::ObjectID; use moveos_std::context::Context; + use moveos_std::object_ref::{Self, ObjectRef}; use rooch_examples::blog; use rooch_examples::blog_add_article_logic; use rooch_examples::blog_create_logic; use rooch_examples::blog_delete_logic; use rooch_examples::blog_remove_article_logic; use rooch_examples::blog_update_logic; + use rooch_examples::article::Article; use std::string::String; friend rooch_examples::article_create_logic; @@ -22,9 +24,10 @@ module rooch_examples::blog_aggregate { public(friend) fun add_article( ctx: &mut Context, - article_id: ObjectID, + article_obj: ObjectRef
, ) { let blog = blog::borrow_blog(ctx); + let article_id = object_ref::id(&article_obj); let article_added_to_blog = blog_add_article_logic::verify( article_id, blog, @@ -32,6 +35,7 @@ module rooch_examples::blog_aggregate { let mut_blog = blog::borrow_mut_blog(ctx); blog_add_article_logic::mutate( &article_added_to_blog, + article_obj, mut_blog, ); blog::update_version(mut_blog); @@ -41,32 +45,31 @@ module rooch_examples::blog_aggregate { public(friend) fun remove_article( ctx: &mut Context, article_id: ObjectID, - ) { + ) : ObjectRef
{ let blog = blog::borrow_blog(ctx); let article_removed_from_blog = blog_remove_article_logic::verify( article_id, blog, ); let mut_blog = blog::borrow_mut_blog(ctx); - blog_remove_article_logic::mutate( + let article_obj = blog_remove_article_logic::mutate( &article_removed_from_blog, mut_blog, ); blog::update_version(mut_blog); blog::emit_article_removed_from_blog(ctx, article_removed_from_blog); + article_obj } public entry fun create( ctx: &mut Context, account: &signer, name: String, - articles: vector, ) { let blog_created = blog_create_logic::verify( ctx, account, name, - articles, ); let blog = blog_create_logic::mutate( ctx, @@ -81,14 +84,12 @@ module rooch_examples::blog_aggregate { ctx: &mut Context, account: &signer, name: String, - articles: vector, ) { let blog = blog::remove_blog(ctx); let blog_updated = blog_update_logic::verify( ctx, account, name, - articles, &blog, ); let updated_blog = blog_update_logic::mutate( diff --git a/examples/blog/sources/blog_create_logic.move b/examples/blog/sources/blog_create_logic.move index c17d9091de..3cbc621eff 100644 --- a/examples/blog/sources/blog_create_logic.move +++ b/examples/blog/sources/blog_create_logic.move @@ -3,9 +3,12 @@ module rooch_examples::blog_create_logic { use moveos_std::object::ObjectID; + use moveos_std::object_ref::ObjectRef; use moveos_std::context::Context; + use moveos_std::table; use rooch_examples::blog; use rooch_examples::blog_created; + use rooch_examples::article::Article; use std::string::String; friend rooch_examples::blog_aggregate; @@ -14,13 +17,11 @@ module rooch_examples::blog_create_logic { ctx: &mut Context, account: &signer, name: String, - articles: vector, ): blog::BlogCreated { let _ = ctx; let _ = account; blog::new_blog_created( name, - articles, ) } @@ -30,8 +31,7 @@ module rooch_examples::blog_create_logic { blog_created: &blog::BlogCreated, ): blog::Blog { let name = blog_created::name(blog_created); - let articles = blog_created::articles(blog_created); - let _ = ctx; + let articles = table::new>(ctx); blog::new_blog( name, articles, diff --git a/examples/blog/sources/blog_created.move b/examples/blog/sources/blog_created.move index e9a63b504a..5c7ed6354f 100644 --- a/examples/blog/sources/blog_created.move +++ b/examples/blog/sources/blog_created.move @@ -8,7 +8,6 @@ module rooch_examples::blog_created { - use moveos_std::object::ObjectID; use rooch_examples::blog::{Self, BlogCreated}; use std::string::String; @@ -16,8 +15,4 @@ module rooch_examples::blog_created { blog::blog_created_name(blog_created) } - public fun articles(blog_created: &BlogCreated): vector { - blog::blog_created_articles(blog_created) - } - } diff --git a/examples/blog/sources/blog_remove_article_logic.move b/examples/blog/sources/blog_remove_article_logic.move index ada26a7d92..1a08b95475 100644 --- a/examples/blog/sources/blog_remove_article_logic.move +++ b/examples/blog/sources/blog_remove_article_logic.move @@ -2,10 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 module rooch_examples::blog_remove_article_logic { - use std::vector; use moveos_std::object::ObjectID; + use moveos_std::object_ref::ObjectRef; + use moveos_std::table; use rooch_examples::article_removed_from_blog; use rooch_examples::blog; + use rooch_examples::article::Article; friend rooch_examples::blog_aggregate; @@ -22,13 +24,9 @@ module rooch_examples::blog_remove_article_logic { public(friend) fun mutate( article_removed_from_blog: &blog::ArticleRemovedFromBlog, blog: &mut blog::Blog, - ) { + ) : ObjectRef
{ let article_id = article_removed_from_blog::article_id(article_removed_from_blog); - let articles = blog::articles(blog); - let (found, idx) = vector::index_of(&articles, &article_id); - if (found) { - vector::remove(&mut articles, idx); - blog::set_articles(blog, articles); - }; + let articles = blog::articles_mut(blog); + table::remove(articles, article_id) } } diff --git a/examples/blog/sources/blog_update_logic.move b/examples/blog/sources/blog_update_logic.move index a5ead30f5e..7a3b415577 100644 --- a/examples/blog/sources/blog_update_logic.move +++ b/examples/blog/sources/blog_update_logic.move @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 module rooch_examples::blog_update_logic { - use moveos_std::object::ObjectID; use moveos_std::context::Context; use rooch_examples::blog; use rooch_examples::blog_updated; @@ -14,7 +13,6 @@ module rooch_examples::blog_update_logic { ctx: &mut Context, account: &signer, name: String, - articles: vector, blog: &blog::Blog, ): blog::BlogUpdated { let _ = ctx; @@ -22,7 +20,6 @@ module rooch_examples::blog_update_logic { blog::new_blog_updated( blog, name, - articles, ) } @@ -33,10 +30,8 @@ module rooch_examples::blog_update_logic { blog: blog::Blog, ): blog::Blog { let name = blog_updated::name(blog_updated); - let articles = blog_updated::articles(blog_updated); let _ = ctx; blog::set_name(&mut blog, name); - blog::set_articles(&mut blog, articles); blog } diff --git a/examples/blog/sources/blog_updated.move b/examples/blog/sources/blog_updated.move index feac026dc2..25d2a4bcde 100644 --- a/examples/blog/sources/blog_updated.move +++ b/examples/blog/sources/blog_updated.move @@ -15,9 +15,5 @@ module rooch_examples::blog_updated { public fun name(blog_updated: &BlogUpdated): String { blog::blog_updated_name(blog_updated) } - - public fun articles(blog_updated: &BlogUpdated): vector { - blog::blog_updated_articles(blog_updated) - } - + } From 48ae3065aec80f7277b82e9aac06ea1972237d3c Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 21:13:02 +0800 Subject: [PATCH 15/18] [examples] blog example --- examples/blog/sources/article.move | 11 ++++++----- examples/blog/sources/article_add_comment_logic.move | 5 +---- examples/blog/sources/article_aggregate.move | 2 -- examples/blog/sources/article_create_logic.move | 2 +- .../blog/sources/article_remove_comment_logic.move | 1 - .../blog/sources/article_update_comment_logic.move | 1 - examples/blog/sources/article_update_logic.move | 1 - examples/blog/sources/blog_updated.move | 1 - 8 files changed, 8 insertions(+), 16 deletions(-) diff --git a/examples/blog/sources/article.move b/examples/blog/sources/article.move index 276f19c288..674ed7ae71 100644 --- a/examples/blog/sources/article.move +++ b/examples/blog/sources/article.move @@ -91,15 +91,16 @@ module rooch_examples::article { article.body = body; } - public(friend) fun add_comment(ctx: &mut Context, article_obj: &mut ObjectRef
, comment: Comment) { + public(friend) fun add_comment(article_obj: &mut ObjectRef
, comment: Comment) { let article = object_ref::borrow_mut(article_obj); let comment_seq_id = comment::comment_seq_id(&comment); assert!(!table::contains(&article.comments, comment_seq_id), ErrorIdAlreadyExists); table::add(&mut article.comments, comment_seq_id, comment); - event::emit(ctx, CommentTableItemAdded { - article_id: id(article_obj), - comment_seq_id, - }); + //TODO enable event after refactor event API to remove `&mut Context` + // event::emit(ctx, CommentTableItemAdded { + // article_id: id(article_obj), + // comment_seq_id, + // }); } public(friend) fun remove_comment(article_obj: &mut ObjectRef
, comment_seq_id: u64) { diff --git a/examples/blog/sources/article_add_comment_logic.move b/examples/blog/sources/article_add_comment_logic.move index 3acffabd73..3a1d8ac7dc 100644 --- a/examples/blog/sources/article_add_comment_logic.move +++ b/examples/blog/sources/article_add_comment_logic.move @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 module rooch_examples::article_add_comment_logic { - use moveos_std::context::Context; use moveos_std::object_ref::ObjectRef; use rooch_examples::article::{Self, Article}; use rooch_examples::comment; @@ -29,7 +28,6 @@ module rooch_examples::article_add_comment_logic { } public(friend) fun mutate( - ctx: &mut Context, _account: &signer, comment_added: &article::CommentAdded, article_obj: &mut ObjectRef
, @@ -39,7 +37,6 @@ module rooch_examples::article_add_comment_logic { let body = comment_added::body(comment_added); let owner = comment_added::owner(comment_added); let id = article::id(article_obj); - let _ = ctx; let _ = id; let comment = comment::new_comment( comment_seq_id, @@ -47,7 +44,7 @@ module rooch_examples::article_add_comment_logic { body, owner, ); - article::add_comment(ctx, article_obj, comment); + article::add_comment(article_obj, comment); } } diff --git a/examples/blog/sources/article_aggregate.move b/examples/blog/sources/article_aggregate.move index 3fa28f09f8..595d57955a 100644 --- a/examples/blog/sources/article_aggregate.move +++ b/examples/blog/sources/article_aggregate.move @@ -75,14 +75,12 @@ module rooch_examples::article_aggregate { ) { let article_obj = article::get_article_mut(ctx, id); let comment_added = article_add_comment_logic::verify( - ctx, account, commenter, body, article_obj, ); article_add_comment_logic::mutate( - ctx, account, &comment_added, article_obj, diff --git a/examples/blog/sources/article_create_logic.move b/examples/blog/sources/article_create_logic.move index 0f33a6d003..c48b610b22 100644 --- a/examples/blog/sources/article_create_logic.move +++ b/examples/blog/sources/article_create_logic.move @@ -5,7 +5,7 @@ module rooch_examples::article_create_logic { use moveos_std::context::Context; use moveos_std::object_ref; use moveos_std::object::ObjectID; - use rooch_examples::article::{Self, Article}; + use rooch_examples::article; use rooch_examples::article_created; use std::string::String; use rooch_examples::blog_aggregate; diff --git a/examples/blog/sources/article_remove_comment_logic.move b/examples/blog/sources/article_remove_comment_logic.move index e1681fcfcd..c9bc73ec54 100644 --- a/examples/blog/sources/article_remove_comment_logic.move +++ b/examples/blog/sources/article_remove_comment_logic.move @@ -3,7 +3,6 @@ module rooch_examples::article_remove_comment_logic { use moveos_std::object_ref::ObjectRef; - use moveos_std::context::Context; use rooch_examples::article::{Self, Article}; use rooch_examples::comment; use rooch_examples::comment_removed; diff --git a/examples/blog/sources/article_update_comment_logic.move b/examples/blog/sources/article_update_comment_logic.move index 87085f9c18..69e419e1b1 100644 --- a/examples/blog/sources/article_update_comment_logic.move +++ b/examples/blog/sources/article_update_comment_logic.move @@ -3,7 +3,6 @@ module rooch_examples::article_update_comment_logic { use moveos_std::object_ref::ObjectRef; - use moveos_std::context::Context; use rooch_examples::article::{Self, Article}; use rooch_examples::comment; use rooch_examples::comment_updated; diff --git a/examples/blog/sources/article_update_logic.move b/examples/blog/sources/article_update_logic.move index e1c32932f5..9110a9d91c 100644 --- a/examples/blog/sources/article_update_logic.move +++ b/examples/blog/sources/article_update_logic.move @@ -4,7 +4,6 @@ module rooch_examples::article_update_logic { use std::signer; use moveos_std::object_ref::{Self, ObjectRef}; - use moveos_std::context::Context; use rooch_examples::article::{Self, Article}; use rooch_examples::article_updated; use std::string::String; diff --git a/examples/blog/sources/blog_updated.move b/examples/blog/sources/blog_updated.move index 25d2a4bcde..6cf78f21df 100644 --- a/examples/blog/sources/blog_updated.move +++ b/examples/blog/sources/blog_updated.move @@ -8,7 +8,6 @@ module rooch_examples::blog_updated { - use moveos_std::object::ObjectID; use rooch_examples::blog::{Self, BlogUpdated}; use std::string::String; From 0f15f00c0b5b9b28fe970a0f365e2de4d10fe247 Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 21:16:31 +0800 Subject: [PATCH 16/18] [examples] Rename simple blog module name --- .../sources/{article.move => simple_article.move} | 3 ++- .../sources/{blog.move => simple_blog.move} | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) rename examples/simple_blog/sources/{article.move => simple_article.move} (96%) rename examples/simple_blog/sources/{blog.move => simple_blog.move} (90%) diff --git a/examples/simple_blog/sources/article.move b/examples/simple_blog/sources/simple_article.move similarity index 96% rename from examples/simple_blog/sources/article.move rename to examples/simple_blog/sources/simple_article.move index d1f474ef28..37161020d0 100644 --- a/examples/simple_blog/sources/article.move +++ b/examples/simple_blog/sources/simple_article.move @@ -1,7 +1,8 @@ // Copyright (c) RoochNetwork // SPDX-License-Identifier: Apache-2.0 -module simple_blog::article { +/// Name the module to `simple_article` for avoid name conflict with `examples/blog` +module simple_blog::simple_article { use std::error; use std::signer; diff --git a/examples/simple_blog/sources/blog.move b/examples/simple_blog/sources/simple_blog.move similarity index 90% rename from examples/simple_blog/sources/blog.move rename to examples/simple_blog/sources/simple_blog.move index 2af22ec087..3c540b0516 100644 --- a/examples/simple_blog/sources/blog.move +++ b/examples/simple_blog/sources/simple_blog.move @@ -1,7 +1,8 @@ // Copyright (c) RoochNetwork // SPDX-License-Identifier: Apache-2.0 -module simple_blog::blog { +/// Name the module to `simple_blog` for avoid name conflict with `examples/blog` +module simple_blog::simple_blog { use std::error; use std::signer; use std::string::{Self,String}; @@ -10,7 +11,7 @@ module simple_blog::blog { use moveos_std::object_ref::{Self, ObjectRef}; use moveos_std::context::Context; use moveos_std::account_storage; - use simple_blog::article::{Self, Article}; + use simple_blog::simple_article::{Self, Article}; const ErrorDataTooLong: u64 = 1; const ErrorNotFound: u64 = 2; @@ -83,7 +84,7 @@ module simple_blog::blog { title: String, body: String, ) { - let article_id = article::create_article(ctx, &owner, title, body); + let article_id = simple_article::create_article(ctx, &owner, title, body); add_article_to_myblog(ctx, &owner, article_id); } @@ -93,7 +94,7 @@ module simple_blog::blog { new_title: String, new_body: String, ) { - article::update_article(ctx, article_obj, new_title, new_body); + simple_article::update_article(ctx, article_obj, new_title, new_body); } public entry fun delete_article( @@ -102,6 +103,6 @@ module simple_blog::blog { article_id: ObjectID, ) { let article_obj = delete_article_from_myblog(ctx, owner, article_id); - article::delete_article(ctx, article_obj); + simple_article::delete_article(ctx, article_obj); } } From 734f5616c97f5a1ba5b965bccd5f29eaad41795c Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 23:12:35 +0800 Subject: [PATCH 17/18] [Doc] Update moveos stdlib docs --- crates/rooch-framework/doc/coin_store.md | 27 ++++++++++++++++++- .../moveos-stdlib/doc/context.md | 5 ++-- .../moveos-stdlib/moveos-stdlib/doc/object.md | 10 ++++--- .../moveos-stdlib/doc/object_ref.md | 2 -- .../moveos-stdlib/sources/object.move | 6 +++-- .../moveos-stdlib/sources/object_ref.move | 4 +-- 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/crates/rooch-framework/doc/coin_store.md b/crates/rooch-framework/doc/coin_store.md index c31ee489df..18d3232d92 100644 --- a/crates/rooch-framework/doc/coin_store.md +++ b/crates/rooch-framework/doc/coin_store.md @@ -18,6 +18,7 @@ - [Function `deposit`](#0x3_coin_store_deposit) - [Function `freeze_coin_store_extend`](#0x3_coin_store_freeze_coin_store_extend) - [Function `create_coin_store_internal`](#0x3_coin_store_create_coin_store_internal) +- [Function `transfer`](#0x3_coin_store_transfer)
use 0x1::error;
@@ -67,7 +68,7 @@ A holder of a specific coin types.
 These are kept in a single resource to ensure locality of data.
 
 
-
struct CoinStore has store, key
+
struct CoinStore has key
 
@@ -413,4 +414,28 @@ Only the CoinType module can freeze or unfreeze a CoinStore by the + + + + +## Function `transfer` + + + +
public(friend) fun transfer(coin_store_obj: &mut object_ref::ObjectRef<coin_store::CoinStore>, owner: address)
+
+ + + +
+Implementation + + +
public(friend) fun transfer(coin_store_obj: &mut ObjectRef<CoinStore>, owner: address){
+    object_ref::transfer_extend(coin_store_obj, owner)
+}
+
+ + +
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md index 7bb35fffe8..b1871995df 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/context.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/context.md @@ -507,8 +507,9 @@ The module of T can borrow mut Object from object store with any object_id ## Function `new_object` -Create a new Object, the default owner is the sender -Add the Object to the global object storage and return the ObjectRef +Create a new Object, Add the Object to the global object storage and return the ObjectRef +Note: the default owner is the System, the caller should explicitly transfer the Object to the owner. +The owner can get the &mut ObjectRef by borrow_object_mut
public fun new_object<T: key>(self: &mut context::Context, value: T): object_ref::ObjectRef<T>
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md
index eb25ee1bb8..d786963f75 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/doc/object.md
+++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object.md
@@ -317,7 +317,7 @@ Create a new object, the object is owned by owner
 
 
 
-
public(friend) fun to_shared<T>(_self: &mut object::Object<T>)
+
public(friend) fun to_shared<T>(self: &mut object::Object<T>)
 
@@ -326,8 +326,9 @@ Create a new object, the object is owned by owner Implementation -
public(friend) fun to_shared<T>(_self: &mut Object<T>) {
+
public(friend) fun to_shared<T>(self: &mut Object<T>) {
     // TODO set the flag
+    transfer_to_system(self);
 }
 
@@ -366,7 +367,7 @@ Create a new object, the object is owned by owner -
public(friend) fun to_frozen<T>(_self: &mut object::Object<T>)
+
public(friend) fun to_frozen<T>(self: &mut object::Object<T>)
 
@@ -375,8 +376,9 @@ Create a new object, the object is owned by owner Implementation -
public(friend) fun to_frozen<T>(_self: &mut Object<T>) {
+
public(friend) fun to_frozen<T>(self: &mut Object<T>) {
     // TODO set the flag
+    transfer_to_system(self);
 }
 
diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md index 67e642d5dd..f55c1a30aa 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/object_ref.md @@ -275,7 +275,6 @@ The shared object also can be removed from the object storage.
public fun to_shared<T: key>(self: ObjectRef<T>) {
     let obj = raw_table::borrow_mut_from_global<T>(&self.id);
     object::to_shared(obj);
-    object::transfer_to_system(obj);
     to_permanent(self);
 }
 
@@ -303,7 +302,6 @@ Make the Object frozen, Any one can not get the &mut ObjectRef from frozen ob
public fun to_frozen<T: key>(self: ObjectRef<T>) {
     let obj = raw_table::borrow_mut_from_global<T>(&self.id);
     object::to_frozen(obj);
-    object::transfer_to_system(obj);
     to_permanent(self);
 }
 
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move index d5d5ce3064..c3eccd2ecc 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/object.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object.move @@ -86,8 +86,9 @@ module moveos_std::object { self.owner = SYSTEM_OWNER_ADDRESS; } - public(friend) fun to_shared(_self: &mut Object) { + public(friend) fun to_shared(self: &mut Object) { // TODO set the flag + transfer_to_system(self); } public(friend) fun is_shared(_self: &Object) : bool { @@ -95,8 +96,9 @@ module moveos_std::object { false } - public(friend) fun to_frozen(_self: &mut Object) { + public(friend) fun to_frozen(self: &mut Object) { // TODO set the flag + transfer_to_system(self); } public(friend) fun is_frozen(_self: &Object) : bool { diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move index b1fbb5aece..8a9b76499a 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/object_ref.move @@ -69,8 +69,7 @@ module moveos_std::object_ref { /// The shared object also can be removed from the object storage. public fun to_shared(self: ObjectRef) { let obj = raw_table::borrow_mut_from_global(&self.id); - object::to_shared(obj); - object::transfer_to_system(obj); + object::to_shared(obj); to_permanent(self); } @@ -78,7 +77,6 @@ module moveos_std::object_ref { public fun to_frozen(self: ObjectRef) { let obj = raw_table::borrow_mut_from_global(&self.id); object::to_frozen(obj); - object::transfer_to_system(obj); to_permanent(self); } From bd6f53b704711a8b48aabc935860a8657f013343 Mon Sep 17 00:00:00 2001 From: jolestar Date: Fri, 27 Oct 2023 23:13:03 +0800 Subject: [PATCH 18/18] fix panic message --- moveos/moveos-types/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moveos/moveos-types/src/state.rs b/moveos/moveos-types/src/state.rs index a3c5b56adb..54e3f1515b 100644 --- a/moveos/moveos-types/src/state.rs +++ b/moveos/moveos-types/src/state.rs @@ -142,7 +142,7 @@ pub trait MoveState: MoveType + DeserializeOwned + Serialize { fn to_runtime_value(&self) -> Value { let blob = self.to_bytes(); Value::simple_deserialize(&blob, &Self::type_layout()) - .expect("Deserialize the MoveValue from MoveState should success") + .expect("Deserialize the Move Runtime Value from MoveState should success") } /// Deserialize the MoveState from MoveRuntime Value