Aptos 上的模块
Aptos 允许在包中进行无需许可的模块发布, 同时也支持对设置了适当兼容性策略的模块进行升级。
模块包含多个结构体和函数,这一点与 Rust 类似。
在包发布时,需要遵守以下约束:
- 结构体和公共函数签名都以不可变的方式发布。
旧方式:init_module(已弃用)
Section titled “旧方式:init_module(已弃用)”以往,模块初始化由 init_module 函数处理:
- 当首次发布模块时(即该模块在链上不存在),VM 会查找并执行
init_module(account: &signer)函数。 - 当升级已存在于链上的模块时,
init_module不会被调用。 - 发布账户的签名者会被传入该函数。它必须是私有的,最多接受一个
&signer参数,不能有泛型参数,也不能返回任何值。
由于这种在发布时隐式执行的机制正在被移除,新模块应改用下面的显式模式。
推荐方式:显式的 initialize entry 函数
Section titled “推荐方式:显式的 initialize entry 函数”暴露一个 entry fun initialize,由模块发布者在发布包之后,通过单独的一笔交易调用它。为其加上保护,使它只能被发布者调用,且只能执行一次:
module my_addr::my_module { use std::signer; use aptos_framework::error;
/// Caller is not the module publisher. const ENOT_AUTHORIZED: u64 = 1; /// Module is already initialized. const EALREADY_INITIALIZED: u64 = 2;
struct ModuleData has key { /* fields */ }
entry fun initialize(publisher: &signer) { assert!(signer::address_of(publisher) == @my_addr, error::permission_denied(ENOT_AUTHORIZED)); assert!(!exists<ModuleData>(@my_addr), error::already_exists(EALREADY_INITIALIZED)); move_to(publisher, ModuleData { /* ... */ }); }}