データを永続的に保存しよう
🎓 データを永続的に保存する方法を知ろう
ICの重要な特徴の1つに、従来のデータベースを使わずにキャニスターの状態を永続化できる点があります。永続化には、ステーブル(Stable)と呼ばれるメモリ領域が用いられます。通常のキャニスター・メモリとは異なり、ステーブルに保存されたデータはアップグレード(データを保持するバックエンドキャニスターの再デプロイなど)を超えて保持されるという特徴があります。データを損失することなくアップグレードに対応するには、ステーブルに保存したいデータをプログラマが自身で定義する必要があります。
stableキーワード
変数の宣言にstableキーワードを使用することで、その変数をステーブルなメモリ領域に保存することを指示できます。
preupgradeとpostupgrade
実は、全ての型の変数がstableキーワードで解決できる訳ではありません。例えばHashMapが挙げられます。ステーブル変数だけでは解決できない場合のために、Motokoはユーザ ー定義のアップグレードフックをサポートしています。このフックは、アップグレードの前後に実行されるものでpreupgradeとpostupgradeという特別な名前を持つsystem関数として宣言されます。アップグレード前に、ステーブルを定義できない変数からステーブル変数へデータを保存し、アップグレード後に元の型へ戻すというフックを定義するという使い方をします。
ここで、永続化を行なっていない現在のDEXでは何が起こるかを確認しておきたいと思います。DEX内にトークンを入金している、かつオーダーを作成している状態を作ります(確認ができれば良いので、以下の画像と全く同じ状況を作り出す必要はありません)。

このようにDEX内にデータが格納されている状態で、main.moを更新してみたいと思います。main.moファイルに定義したlast_id変数の初期値を修正して再デプロイを行います。
private var last_id : Nat32 = 100; // TODO: 後で初期値0に戻す
dfx deploy icp_basic_dex_backend
ブラウザをリロードしてみると、DEXに預けたトークンとオーダーの情報が取得できていない(リセットされた)ことが確認できます。ただし、預けていないトークンの情報は保持されています。これは、DIP20が永続化を行なっているためです。コードを覗いてみるとわかりますが、stable変数が定義されています。

それでは、大切なデータが失われないように永続化を行うためのコードを追加していきましょう。