パッケージでアップグレード可能な部分を理解するには、まずアップグレード可能性の基本前提を理解する必要があります。アップグレードは、以前のバージョンとの公開互換性を壊すべきではありません。依存パッケージで使用できるモジュールの部分は、静的シグネチャを変更すべきではありません。これは以下に適用されます:
// モジュールはパッケージから削除できません
module book::upgradable {
// 依存関係は変更可能です(公開シグネチャで使用されていない場合)
use std::string::String;
use sui::event; // 削除可能
// 公開構造体は削除や変更ができません
public struct Book has key {
id: UID,
title: String,
}
// 公開構造体は削除や変更ができません
public struct BookCreated has copy, drop {
/* ... */
}
// 公開関数は削除できず、シグネチャも変更できません
// ただし、実装は変更可能です
public fun create_book(ctx: &mut TxContext): Book {
create_book_internal(ctx)
// 削除や変更が可能
event::emit(BookCreated {
/* ... */
})
}
// パッケージ可視性の関数は削除や変更が可能です
public(package) fun create_book_package(ctx: &mut TxContext): Book {
create_book_internal(ctx)
}
// エントリー関数は公開されていない限り、削除や変更が可能です
entry fun create_book_entry(ctx: &mut TxContext): Book {
create_book_internal(ctx)
}
// プライベート関数は削除や変更が可能です
fun create_book_internal(ctx: &mut TxContext): Book {
abort 0
}
}
パッケージの以前のバージョンを破棄するために、オブジェクトにバージョンを付けることができます。オブジェクトにバージョンフィールドが含まれ、オブジェクトを使用するコードが特定のバージョンを期待し、アサートする限り、コードを新しいバージョンに強制的に移行できます。通常、アップグレード後、管理者機能を使用して共有状態のバージョンを更新し、新しいバージョンのコードを使用できるようにします。古いバージョンはバージョンの不一致でアボートします。
module book::versioned_state {
const EVersionMismatch: u64 = 0;
const VERSION: u8 = 1;
/// 共有状態(所有も可能)
public struct SharedState has key {
id: UID,
version: u8,
/* ... */
}
public fun mutate(state: &mut SharedState) {
assert!(state.version == VERSION, EVersionMismatch);
// ...
}
}
Suiには、同じオブジェクトシグネチャを保持しながら、オブジェクトの保存された設定を変更できる一般的なパターンがあります。これは、ベースオブジェクトをシンプルでバージョン管理されたものに保ち、実際の設定オブジェクトを動的フィールドとして追加することで実現されます。このアンカーパターンを使用することで、同じベースオブジェクトシグネチャを保持しながら、パッケージのアップグレードで設定を変更できます。
module book::versioned_config {
use sui::vec_map::VecMap;
use std::string::String;
/// ベースオブジェクト
public struct Config has key {
id: UID,
version: u16
}
/// 実際の設定
public struct ConfigV1 has store {
data: Bag,
metadata: VecMap<String, String>
}
// ...
}
このセクションは近日公開予定です!
The Move Book へ戻る