CryptoZombies #1 備忘録





<br/>
こんにちは。サトミです。
普段は、dapps開発、ブロックチェーンリサーチなどをしています。
ブロックチェーンしかTweetしないアカウントを最近作りました。
dapps、海外のブロックチェーンニュース...etc=>[@satomin_dev](https://twitter.com/satomin_dev)



本エントリは、CryptoZombiesの備忘録です。




# CryptoZombiesとは？

<br/>
![preview-zombie.png](https://qiita-image-store.s3.amazonaws.com/0/244700/ce6f1d53-90ac-76ec-f443-a842b999ab35.png)

[Loom Network](https://loomx.io/)が提供している、Solidityゲーム感覚で学べるサービス。
※ Solidity：Ethereum上にデプロイするスマートコントラクトを書くための言語

おそらくdapps開発者が一度は触るもので、もはや通過儀礼的な立ち位置。





# 概要

６つのレッスンがある。

1. ゾンビファクトリーの作成
2. ゾンビが人間を襲う
3. Solidityの高度なコンセプト
4. ゾンビのバトルシステム
5. ERC721とクリプト収集物
6. アプリのフロントエンドとWeb3.js

６回に分けてそれぞれのまとめを置いておきます。




# 1. ゾンビファクトリーの作成

Solidityのコンパイラのバージョンの宣言。
※ CryptoZombiesでは0.4.19を指定する。
<br/>


```
pragma solidity ^0.4.19;

contract ZombieFactory {
}
```

理由：将来コンパイラのバージョンが原因でコードが壊れることを防ぐ
<br/>

状態変数の定義
※ 状態変数：Ethereumブロックチェーンに記録される。

```
pragma solidity ^0.4.19;

contract ZombieFactory {
    uint dnaDigits = 16;
}
```
 uint：符号なし整数のデータ型で、256bitのエイリアス

### - 構造体

複数のプロパティを持つデータ型を作成できる。

```
pragma solidity ^0.4.19;

contract ZombieFactory {
    uint dnaDigits = 16;  
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }
}
```

ここではZombieという構造体を作成し、string型のnameとuint型のdnaをもたせている。


### - 配列

メモリを無駄遣いしないように、２種類の配列がある。
固定長配列

```
uint[2] fixedArray;
```
可変長配列

```
uint[] dynamicArray;
```
<br/>
`zombies`という配列を作り、`createZombie`functionの中で、新しいZombieを配列に格納していく。
<br/>

```
pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

    Zombie[] public zombies;

    function createZombie(string _name, uint _dna) {
        zombies.push(Zombie(_name, _dna));
    }

}

```
### - Private / Public

Public：誰でもコントラクトの関数を叩け、実行できる。
Private：定義されたコントラクト内でのみ使用することができる。
※ デフォルトは`Public`で設定されている。
<br/>

createZombie関数を`Private`にする。
その際、createZombie => `_createZombie`に変更するのが通例。


### - View / Pure

View：ブロックチェーンに記録、値の変更、書き込みができないが、読み込みはできる。
Pure：書き込み、読み込み共にできない。

_generateRandomDna関数を`private`、`view`で設定し、戻り値をuint型の16ケタに設定する。

```
pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

    Zombie[] public zombies;

    function _createZombie(string _name, uint _dna) private {
        zombies.push(Zombie(_name, _dna));
    } 

    function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
    }

}

```
returns (type)：関数の宣言に戻り値の型を含む
keccak256()：16進数に変換したハッシュ値を求める（同じ文字からは同じハッシュ値）
uint()：型キャスト

今まで作ってきた関数を`createRandomZombie`関数にまとめる。

```
pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

    Zombie[] public zombies;

    function _createZombie(string _name, uint _dna) private {
        zombies.push(Zombie(_name, _dna));
    } 

    function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
    }

    function createRandomZombie(string _name) public {
        uint randDna = _generateRandomDna(_name);
        _createZombie(_name, randDna);
    }

}

```
### - Events

・コントラクト上で発生したことをDappsなどのクライアントに通知することができる。
・渡されたパラメータはトランザクションのログに保持される。

イベントの宣言はこのような感じ。

```
event EventName(type params);
```

`NewZombie`というEventを宣言して、指定のパラメータを渡す。

`_createZombie`関数内で、`zombies`配列に追加されたら、イベントを発火させる。

ゾンビの`id`には、配列のインデックスを付与させる。
`array.push()`関数が配列の要素数を返すことを利用し、`array.push()-1`で対応。

```
pragma solidity ^0.4.19;

contract ZombieFactory {

    event NewZombie(uint zombieId, string name, uint dna);
    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

    Zombie[] public zombies;

    function _createZombie(string _name, uint _dna) private {
        uint id = zombies.push(Zombie(_name, _dna)) - 1;
        NewZombie(id, _name, _dna);
    } 

    function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
    }

    function createRandomZombie(string _name) public {
        uint randDna = _generateRandomDna(_name);
        _createZombie(_name, randDna);
    }

}

```
#### DONEです、お疲れ様でした。

#### 次回： 「ゾンビが人間を襲う」



---


#### bportal

[![bportal_service@2x.png](https://qiita-image-store.s3.amazonaws.com/0/244700/3f0585a7-e151-1e16-30d7-2c8da4406a8a.png)](https://bportal.jp)