Solidityの変数はストレージ、又はメモリーに格納できる。
パソコンのハードディスクとRAMと同じようなイメージでOK。
それぞれの特徴をまとめておく。
storage
ブロックチェーン上に永久に格納される変数。
状態変数(関数外で宣言された変数)はデフォルトでstorageになる。
storageに保存されるデータはブロックチェーンに格納される = 全てのノードで保存されるということになるため、非常にコスト(gas)が高い。
memory
コントラクト実行時のみ保持される変数。
そのため、ブロックチェーンに保存されることはない。
ブロックチェーンに保存されないため、コストもかからない。
関数内で宣言された変数はデフォルトでmemoryになる。
関数の実行が完了すれば消えてしまう。(ローカル変数が関数外で使用できないのと同じイメージ)
尚、memoryの配列は必ずサイズを指定して作成する必要がある。
サンプル
contract GameFactory {
struct Game {
string name;
string status;
}
// 状態変数(関数外の変数)はデフォルトでstorageになる
Game[] games;
function clearGame(uint _index) public {
// この場合はコンパイラがstorageかmemoryを指定しろと警告してくれる
// Game myGame = games[_index];
// ブロックチェーン内のgames[_index]への参照(ポインタ)が格納される
Game storage myGame1 = games[_index];
// そのためブロックチェーンを直接更新できる(games[_index].statusも"clear"になる)
myGame1.status = "clear";
// 値をコピーするだけならmemoryを使用する
Game memory myGame2 = games[_index + 1];
// 一時的にコピーした値を変更しているだけなので、games[_index + 1].statusは変更されない
myGame2.status = "clear";
// memoryの内容をブロックチェーンに反映したい場合
games[_index + 1] = myGame2;
// memoryの配列は必ずサイズを指定する
uint[] memory values = new uint[](3);
values.push(1);
}
}