初心者文系主婦がブロックチェーンを学ぶブログ

IT革命のビッグウェーブに乗り遅れた主婦が、ブロックチェーン革命の波にのるべく、ブロックチェーン技術を学ぶブログです。

【CryptZombies】レッスン2チャプター7:ストレージVSメモリ

StroageとMemory

Storageブロックチェーン上に永久に格納される変数です。

状態変数(関数外で宣言された変数のこと)の場合はデフォルトでstorageで格納されます。

Memoryは一時的な変数で、外部関数をコントラクトに呼び出す際に消去されます。

関数内で宣言された変数はmemoryとして扱われて、関数の呼び出しが終われば消えるように設定されています。

contract SandwichFactory {
  struct Sandwich {
    string name;
    string status;
  }

  Sandwich[] sandwiches;

  function eatSandwich(uint _index) public {
    // Sandwich mySandwich = sandwiches[_index];
  (新しく作った「mySandwich」Sandwichは、sandwiches配列の「_index」インデックスが示す変数と等しいという意味。) // ^ かなり簡単に見えるが、この場合Solidityが明示的に`storage` や `memory`を // 宣言するように警告が出るはずだ。 // そこで、`storage`と宣言してみるぞ: Sandwich storage mySandwich = sandwiches[_index]; //...この場合`mySandwich`がstorage内の`sandwiches[_index]`を // 示すポインタだから... mySandwich.status = "Eaten!"; // ...これで`sandwiches[_index]`をブロックチェーン上でも永久に変更することになる。 // コピーしたいだけなら、`memory`の方が便利だ: Sandwich memory anotherSandwich = sandwiches[_index + 1]; // ...この場合`anotherSandwich`は memory内のデータを // コピーすることになり... anotherSandwich.status = "Eaten!"; // ...一時的な変数を変更するだけで、`sandwiches[_index + 1]`には // なんの影響もない。次のようにすることも可能だ: sandwiches[_index + 1] = anotherSandwich; // ...ブロックチェーンのstorageに変更したい場合はこうだ。 } }

storageを使うべきか、memoryを使うべきかは、Solidityのコンパイラが教えてくれるので、あまり悩む必要はないみたいです。

 

テストの実行

feedAndMultiplyという関数を作成せよそこに_zombieId(uint)と_targetDna(uint)の2つのパラメータを設定せよこの関数はpublicで作成せよ

まず赤線から見ていきます。

feedAndMultiplyという名前の関数を作成します。

f:id:nomadomama:20181130000215p:plain

次に青線を見ていきます。

上で作成したfeedAndMultiply関数に_zombieId(uint)と_targetDna(uint)の2つのパラメータを設定します。

f:id:nomadomama:20181130000416p:plain

 最後にオレンジ線を見ていきます。

作成した関数をpublic関数に設定します。

f:id:nomadomama:20181130000536p:plain

 

②我々のゾンビに他の誰かが餌を与えるのは見たくない!そこでまずゾンビが我々のものだと確認するようにしたい。そこで、requireステートメントを追加してmsg.senderがこのゾンビのオーナーであるかどうかを確認せよ(createRandomZombie関数を作成した時のやり方を参考にせよ)

まず赤線を見ていきます。

createRandomZombie関数は別タブのzombieFactory.solに格納されているので、そちらのタブを参照します。

f:id:nomadomama:20181130001011p:plain

次に青線を見ていきます。

ゾンビのオーナーを確認するために、zombieFactory.solで作成したzombieToOwnerマッピングのキー(_zombieId)を指定して、バリューとして呼び出されるaddressがmsg.sender(関数を呼び出したユーザーのaddress)と等しいか、requireステートメントを使って確認します。

こちらが作成済みのzombieToOwnerマッピング

f:id:nomadomama:20181130002134p:plain

requireステートメントを使用して、次のように確認します。

f:id:nomadomama:20181130003604p:plain

 

③ゾンビのDNAを手に入れる必要がある。そこでmyZombieという名前のローカルzombie(storageポインタとする)を関数で宣言する必要がある。この変数をzombies配列内の_zombieIdインデックスと同じにせよ。この課題は}を含めて4行以内で記述すること。

まず赤線から見ていきます。

zombieFactory.solで作成したzombie構造体を利用して、myZombieという名前のローカルzombieをstorageポインタを追加して宣言します。

f:id:nomadomama:20181130003659p:plain

次に青線を見ていきます。

 上で作成したmyZombieという名前のローカルゾンビの変数を、zombies配列内の_zombieIdインデックスと等しくなるよう定義します。

f:id:nomadomama:20181130003752p:plain

 

お疲れさまでした!

 

 

<参考>

CryptoZombies - イーサリアム上でゲームを開発する方法を学習。Powered by Loom Network