rooch-network / rooch

VApp Container with Move Language
https://rooch.network
Apache License 2.0
128 stars 54 forks source link

[move stdlib] Remove the `store` ability requirement from account resource function #1623

Closed jolestar closed 1 week ago

jolestar commented 3 weeks ago

Motivation

To keep compatibility with the Move borrow_global|move_to|move_from instruction, we need to remove the store ability requirement from the account resource function. In the future, we can support auto convert borrow_global to account::borrow_resource.

public fun borrow_resource<T: key + store>(account: address): &T

to

public fun borrow_resource<T: key>(account: address): &T
pause125 commented 2 weeks ago

How can we remove store ability as T is stored in object field, which requires store ability?

jolestar commented 2 weeks ago

How can we remove store ability as T is stored in object field, which requires store ability?

Use the object module's internal functions.

fun add_field_internal<T: key, K: copy + drop, V>(obj_id: ObjectID, key: K, val: V) 

make it public(friend).

public fun account_move_resource_to<T: key + store>(self: &mut Object<Account>, resource: T){
      assert!(!object::contains_field(self, key<T>()), ErrorResourceAlreadyExists);
      object::add_field(self, key<T>(), resource)
   }

to

public fun account_move_resource_to<T: key>(self: &mut Object<Account>, resource: T){
      assert!(!object::contains_field(self, key<T>()), ErrorResourceAlreadyExists);
      object::add_field_internal(object::id(self), key<T>(), resource)
   }
pause125 commented 2 weeks ago

Actually, here is definition of object::add_field_internal:

fun add_field_internal<T: key, K: copy + drop, V>(obj_id: ObjectID, key: K, val: V) {
      native_add_field<K, FieldValue<V>>(obj_id, key, FieldValue{val});
      increment_size<T>(obj_id);
  }

V is store in FieldValue, is that mean V must have store ability to be stored as FieldValue's field?

jolestar commented 2 weeks ago

The V of FieldValue<V> does not require any ability.

struct FieldValue<V> has key, drop, store {
    val: V
}

It should be worked.