😸

[Astar]wasmコントラクトのアップグレード可能なコントラクトについて

2023/02/28に公開

この記事は、こちらの「アップグレード可能なコントラクト」の部分を補足を加えながら日本語訳したものです。
https://docs.openbrush.io/smart-contracts/upgradeable

何度もすらすら読むべき内容だと思ったので、翻訳しました。

アップグレード可能なコントラクトの種類

アップグレード可能なコントラクトには、3つのタイプがあります。

  1. プロキシパターン
  • 長所
    バグが発生しにくい基本的なパターン
  • 欠点
    1回呼び出すごとに追加のコントラクトと追加のオーバーヘッドを配置する必要がある
  1. set_code_hash メソッドの使用
  • 長所
    set_code_hash メソッドを公開するだけで、コントラクトを簡単にアップグレードできる。
  • 短所
    アップデートの際に公開し忘れると、アップグレードができなくなる
  1. ダイヤモンド・スタンダード・パターン
  • 長所
    コントラクトをファセット(ロジック層)に分割することで、コントラクトのパフォーマンスを最適化し、コントラクトのサイズ制限を克服できる。
    ファセット(ロジック層)を個別にアップグレードでき、ロジック層ごとに異なるガバナンスルールを使用できる。
  • 短所
    重複する特定のロジックユニットに対してより多くのオーバーヘッドが発生する
    ストレージが破損する可能性が高い
    優れたデプロイメント管理が必要

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