Sui Move中transfer::share_object与transfer::public_share_object的区别
核心区别
transfer::share_object:将对象转为共享状态后,仅同包内的代码可以利用对象的key能力执行修改操作(比如修改私有字段、调用同包可见的修改方法);外部包只能调用该对象的public方法(如果存在),无法直接修改对象状态。transfer::public_share_object:共享对象后,任何包的代码都能通过对象的key能力修改其状态,相当于完全开放修改权限,风险极高,仅在特殊场景下使用。
实现「仅同包可修改、外部无法修改」的共享对象
你的需求完全可以通过transfer::share_object配合Move的访问控制机制实现,核心要点如下:
- 使用
transfer::share_object共享对象,而非public_share_object; - 将对象的修改逻辑封装为同包可见的非public函数(Move中默认函数权限为同包可见,无需额外修饰);
- 确保对象的字段为私有(Move默认字段私有,无需加
public修饰),避免外部直接访问修改; - 若需外部访问对象数据,提供
public的查询方法即可。
示例代码:
module my_package::my_shared_obj { use sui::transfer; use sui::object::{Self, UID}; use sui::tx_context::{Self, TxContext}; // 定义带key能力的共享对象,字段默认私有 struct MySharedObj has key, store { id: UID, value: u64, } // 公开的创建共享对象入口 public fun create(ctx: &mut TxContext) { let obj = MySharedObj { id: object::new(ctx), value: 0, }; // 用share_object共享,限制仅同包可修改 transfer::share_object(obj); } // 同包可见的修改方法,外部无法调用 fun update_value(obj: &mut MySharedObj, new_value: u64) { obj.value = new_value; } // 外部可调用的查询方法 public fun get_value(obj: &MySharedObj): u64 { obj.value } }
在这个示例中:
- 外部包只能调用
create和get_value方法,无法调用update_value修改对象; - 只有同包内的其他函数可以调用
update_value来修改MySharedObj的状态; - 因为使用了
transfer::share_object,外部即使拿到对象引用,也无法绕过权限直接修改私有字段。
内容的提问来源于stack exchange,提问作者Ice
相关产品推荐
相关产品推荐

