Skip to content
This repository has been archived by the owner on May 4, 2024. It is now read-only.

[Feature Request]TypeTable #140

Open
jolestar opened this issue May 15, 2022 · 0 comments
Open

[Feature Request]TypeTable #140

jolestar opened this issue May 15, 2022 · 0 comments
Labels
enhancement New feature or request

Comments

@jolestar
Copy link
Collaborator

🚀 Feature Request

Motivation

I have mentioned the idea of TypeTable in the documentation of Table, and I describe it in more detail here.

According to the implementation of Table(#150), we get:

module Std::Table {
    native struct Table<K, V: store> has store;
    native fun create<K, V>(): Table<K, V>
    native fun destroy<K, V>(t: Table<K, V>);
    native fun insert<K, V>(t: &mut Table<K, V>, k: &K, v: V);
    native fun remove<K, V>(t: &mut Table<K, V>, k: &K): V;
    native fun contains_key<K, V>(t: &Table<K, V>, k: &K): bool;
    native fun borrow<K, V>(t: &Table<K, V>, k: &K): &V;
    native fun borrow_mut<K, V>(t: &mut Table<K, V>, k: &K): &mut V;
}

But this Table can only use type K's value as the key, not type K as the key like borrow_global.

So I suggest introducing TypeTable with the basic operations described below:

module Std::TypeTable {
   native struct TypeTable has store;
   native fun create(): TypeTable
   native fun destroy(t: TypeTable);
   native fun insert<T>(t: &mut TypeTable, v: T);
   native fun remove<T>(t: &mut TypeTable<K>): T;
   native fun contains_key<T>(t: &TypeTable<T>): bool;
   native fun borrow<T>(t: &TypeTable): &T;
   native fun borrow_mut<T>(t: &mut TypeTable<T>): &mut T;
}

Now, we can define a AccountStorage struct in Move:

module Std::Account{
   struct AccountStroage{
      resources: TypeTable,
      moudles: Table<Identifer,vector<u8>>,
   }
}

Then we bind the table when Account create, such as:

module Std::Account{
    public fun create_account(addr: address){
        let resources = TypeTable::create();
        let modules = Table::create<Identifer,vector<u8>>();
        let account_storage = AccountStorage{
            resources,
            modules,
         };
         native_save_account(addr,account_storage);
    }

    public fun borrow<T>(addr:address):&T{
      let account_storage = native_get_account_staroge(addr);
      //This expression is not available in the current Move
      //We can not return ref like this, but we can ignore it now.
      return TypeTable::borrow<T>(&account_storage.resources);
    }

    public fun move_to<T>(signer:&signer, t:T){
      //if do not want to limit signer, can use address.
      let addr = Signer:address_of(signer);
      let account_storage = native_get_account_staroge(addr);
      TypeTable::insert(&mut account_storage.resources,t);
    }
   
    //We can update or deploy code in Move now, like `create2` in ethereum.
    public fun update_module(signer:&signer, name:Identifer, code:vector<u8>){
       let account_storage = native_get_account_staroge(addr);
       account_storage.modules.insert(name, code);
    }
}
  • Now, borrow_global(address) = Account::borrow(address),
    and move_to(siger) = Account::move_to(siger), global_storage operation can been eliminate.
  • The transaction ChangeSet are all table_changes.
  • Every Move chain framework can customize their own account storage via the TypeTable and native function.

This feature can implement via an extension like Table and the backend storage is the same as Table, but TypeTable needs the same security guarantees as borrow_global.

We have two approaches to achieving this goal:

  1. Introduce TypeTable into core instead of extension, add security restrictions to TypeTable::borrow similar to borrow_global.
  2. Introduce the visibility of Struct and let the smart contract developer can control the access of Struct, see issue [Feature Request]Introduce Visibility to Struct #139.

Migrate from diem/move, previous discussion diem/move#158

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant