[Astar]wasmコントラクトのアップグレード可能なコントラクトについて
この記事は、こちらの「アップグレード可能なコントラクト」の部分を補足を加えながら日本語訳したものです。
何度もすらすら読むべき内容だと思ったので、翻訳しました。
アップグレード可能なコントラクトの種類
アップグレード可能なコントラクトには、3つのタイプがあります。
- プロキシパターン
- 長所
バグが発生しにくい基本的なパターン - 欠点
1回呼び出すごとに追加のコントラクトと追加のオーバーヘッドを配置する必要がある
- set_code_hash メソッドの使用
- 長所
set_code_hash メソッドを公開するだけで、コントラクトを簡単にアップグレードできる。 - 短所
アップデートの際に公開し忘れると、アップグレードができなくなる
- ダイヤモンド・スタンダード・パターン
- 長所
コントラクトをファセット(ロジック層)に分割することで、コントラクトのパフォーマンスを最適化し、コントラクトのサイズ制限を克服できる。
ファセット(ロジック層)を個別にアップグレードでき、ロジック層ごとに異なるガバナンスルールを使用できる。 - 短所
重複する特定のロジックユニットに対してより多くのオーバーヘッドが発生する
ストレージが破損する可能性が高い
優れたデプロイメント管理が必要
Proxyパターン
Proxy
パターンには2つのコントラクトがある。最初のコントラクトは単純なラッパーで、ユーザーが直接操作する「プロキシ」であり、2番目のコントラクトであるロジックレイヤーへの呼び出しを転送する役割を果たす。ロジックレイヤーは交換可能であるが、プロキシは交換できない。ロジックレイヤーをアップグレードするには、ロジックレイヤーのコードハッシュを新しいものに置き換える必要があります。
プロキシはアップグレードできないので、簡単です。プロキシはOpenBrushの実装を流用して作成することができます。ロジック層は、上記のルールに従ったほうがよいでしょう。
以下は、delegate_callを使ったProxyコントラクトのイメージです。
chatGPT
chatGPT
OpenBrushはProxyパターンをデフォルトで実装しています。proxy::Dataロジックユニットを持ち、その中にforward_toを格納します。ストレージユニットはproxy::STORAGE_KEYのストレージキーを占有しています。forward_toはロジック層のソースコードのコードハッシュです。また、コントラクト内部のforward_toの値のコードハッシュを更新するためのchange_delegate_callメソッドも含まれています。change_delegate_callメソッドは、オーナーだけが呼び出すことができます。
pub const STORAGE_KEY: u32 = openbrush::storage_unique_key!(Data);
#[derive(Default, Debug)]
#[openbrush::storage(STORAGE_KEY)]
pub struct Data {
pub forward_to: Hash,
}
set_code_hash メソッドの使用法
インク!には ink_env::set_code_hash メソッドがあり、現在のコントラクトのコードハッシュを置き換えることができます。つまり、オンデマンドで新しいコードハッシュを指定することで、ロジックレイヤーを変更することができるのです。新しいコードハッシュを設定した後、次にコントラクトを呼び出すと、更新されたロジックが実行されます。
そのメソッドを何らかの方法で公開するだけで、共通のコントラクトはアップグレード可能です。例えば、そのメソッドを追加すれば、それで完了です。
#[ink(message)]
pub fn upgrade_my_contract(&mut self, new_code_hash: Hash) {
ink_env::set_code_hash(&new_code_hash)
}
制限された人だけがその機能を呼び出すことができるはずなので、権限システムを考慮する必要があります。
上に述べたすべての提案は、その種のアップグレード可能なコントラクトに適用できます。アップグレード可能なストレージのレイアウト、コントラクトの新しいバージョンのための初期化機能、パーミッションシステムなどを用意するのがベターでしょう。
ダイヤモンド・スタンダード
こちらは、理解が完了後に翻訳してきます。
Discussion