はじめに
ブロックチェーンのユースケースの一つとして「何かの履歴」を証明として残すということがあると思います.
Ethereumとかを使うと,RAMエコシステムがないので,ストレージ利用は高価.データを消してもETHは戻らない.
でもIOSTの場合はRAMエコシステムがあるおかげで,使い終わったストレージ領域は削除するとRAMトークンが返却されてストレージの再利用ができる.
なので,IOSTの場合は使わなくなったストレージは積極的に削除すべきということだ.
ストレージデータのいいところは「書き換えられる」ということだ.でも履歴データって書き換えますか??ないですよね.
じゃあ履歴データはずっとRAMに残しておく必要は無いですよね.
とりあえずスマートコントラクトのコードを見ていきましょう.
悪い例
ずっとRAMに履歴を記録していくスタイル
class BadHistory {
init() {}
add(attr, action) {
const history = JSON.parse(storage.mapGet(tx.publisher, attr)) || [];
history.push(action);
storage.mapPut(tx.publisher, attr, JSON.stringify(history));
}
destroy(attr) {
storage.mapDel(tx.publisher, attr);
}
}
これだと,履歴データが増えるにつれてRAMの使用料がかさんでいきます.(この例だとGASもかかってきますね.)
提案する方法
class NiceHistory {
init() {}
add(attr, action) {
const prev = storage.mapGet(tx.publisher, attr);
if (tx.hash === prev)
throw new Error('duplicated tx hash');
blockchain.receipt(JSON.stringify({ action, prev }));
storage.mapPut(tx.publisher, attr, tx.hash);
}
destroy(attr) {
storage.mapDel(tx.publisher, attr);
}
}
これだと,履歴が増えてもRAMの利用は一定値のままになる.
アイデアは,ブロックチェーンの上にチェーン作ってしまおうって感じ.
最新の履歴のTxHashだけRAMに記録しておいて,更新があるたびにreceiptに流す.
参照方法は,最初RAMにアクセスして最新Txを得てgetTxReceiptでデータを取得,そのreceiptにさらに一つ前のTxHashが乗っているので同様に参照...を続けていく.TxHashがnullになれば終了だ.
この方法のデメリットは,全履歴へのアクセスまでに時間がかかるという点だ.