CryptZombiesレッスン6の自分なりのまとめ

# はじめに
この記事は私がCryptZombiesを進めていく上で自分なりにまとめたものです。
**前回の記事**
https://qiita.com/daichi77/items/828091754290c5368d20
**参考にしたサイト**
サイト名: イーサリアム上のDApp開発をゲームを作って学びましょう
URL: 　https://cryptozombies.io/jp/　
**この記事の問題文と答えについては上の参考にしたサイトから引用しています。**

# チャプター１ Web3.js入門
## 要点
**web3.jsをプロジェクトに追加**

```html
<script language="javascript" type="text/javascript" src="web3.min.js"></script>
```
githubからファイルダウンロードしてこのコードを埋め込めばok。
## 今回やったこと(テスト)
上のコードをコピペしてプロジェクトにweb3.jsを追加。

## チャプター２ Web3プロバイダ
**Web3プロバイダ**
どのノードに読み書きを処理させるよう働き掛けるかをコードに教えてくれる。
APIコールをするためにリモートのウェブサーバーのURLを設定するようなものだ。
**Infura**
高速な読み込みのためのキャッシュレイヤーをもつイーサリアム・ノードのセットを保持するサービスで、API経由でこれらのノードに無料でアクセスすることができる
InfuraをWeb3プロバイダとして使うために次のように書く必要がある。

```js
var web3 = new Web3(new Web3.providers.WebsocketProvider("wss://mainnet.infura.io/ws"));
```
**Metamask**
MetamaskはChromeとFirefoxのブラウザ拡張機能で、ユーザーは自分のイーサリアム・アカウントと秘密鍵を安全に管理し、そのアカウントでWeb3.jsを使用しているウェブサイトとやりとりすることが可能である。

```js
window.addEventListener('load', function() {

  // Web3がブラウザにインジェクトされているかチェック (Mist/MetaMask)
  if (typeof web3 !== 'undefined') {
    // Mist/MetaMaskのプロバイダの使用
    web3js = new Web3(web3.currentProvider);
  } else {
    // ユーザーがweb3を持たない場合の対処。
    // アプリを使用するためにMetamaskをインストールするよう
    // 伝えるメッセージを表示。
  }

  // アプリのスタート＆Web3.jsへの自由なアクセスが可能に:
  startApp()

})
```
このテンプレートでユーザーがブラウザにmetamaskをインストールしているかを確かめることができる。

# チャプター３ コントラクトへのアクセス
## 要点
web3.jsがコントラクトにアクセスするために**アドレス**と**ABI**が必要
**コントラクトアドレス**
スマートコントラクトをコンパイルしてデプロイしたときに与えられる永久に有効なイーサリアム上の固定アドレス
**コントラクトABI**
Application Binary Interfaceの略
これはコントラクトのメソッドをJSON形式で表していて、関数コールをコントラクトが理解できるようフォーマットする方法を、Web3.jsに教えてくれるもの。
コントラクトのアドレスとABIが分かったら次の文でインスタンス化できる

```js
var myContract = new web3js.eth.Contract(myABI, myContractAddress);
```

## 今回やったこと(テスト)
- cryptozombies_abi.jsをimport
- startApp関数の定義
- 上記に書いてあるコードをいじってコントラクトのインスタンス化

# チャプター４ コントラクトの関数呼び出し
## 要点
**Call**
view関数およびpure関数に使われる。これはローカルのノードでのみ機能し、ブロックチェーン上のトランザクションを生成しない。

```js
myContract.methods.メソッド名(123).call()
```
このように使うことができる
**Send**
sendはトランザクションを生成し、ブロックチェーン上のデータを変更する。viewまたはpureではない関数には、sendを使う必要がある。
先ほどと同じような感じで使える。

```js
myContract.methods.myMethod(123).send()
```

## 今回やったこと(テスト)
zombieToOwnerを呼び出すための関数とgetZombiesByOwnerを呼び出すための関数を作成

# チャプター５ Metamaskとアカウント
## 要点
(やろうとしていること)
アクティブユーザーが切り替わるとそれに応じて画面にそのユーザーのゾンビを全て表示する。
この章でやっているのはユーザーが切り替わるたびにそのユーザーのゾンビを取得するまで。
おそらくdisplayZombiesで画面に表示する部分をやると思うが、この章ではメソッドの中身は実装されていない。

```js
var userAccount = web3.eth.accounts[0]
```
これでMetamaskのアクティブアカウントを確認することができる。

```js
var accountInterval = setInterval(function() {
  // アカウントが変更されているかチェック
  if (web3.eth.accounts[0] !== userAccount) {
    userAccount = web3.eth.accounts[0];
    // 新アカウントでUIをアップデートするように関数コール
    updateInterface();
  }
}, 100);
```
これで100ミリ秒ごとにアクティブユーザーを確認。

今回したこと（テスト)
上記のコードとgetZombiesByOwner.then(displayZombies);を使って一定時間ごとにアクティブユーザーの確認&displayZombies関数の呼び出しまで実装。これであとはdisplayZombies関数を書けばゾンビの更新完了

# チャプター６
## 要点
**displayZombies関数の概要**
1. #zombies divの中身に何かあった場合は、それを消去する
(例えばuser1からuser2に更新するとき前のやつを消去しないとuser1とuser2のどちらも表示されてしまうから)
2. for文を使ってgetZombieDetails(id)を呼び出す。
3. ゾンビ情報を表示向けにフォーマットするようHTMLテンプレートに取り込み、そのテンプレートを#zombies divに追加する。

# 今回やったこと(テスト)
1. $("#zombies").empty();を使ってdivの中身を削除
2. for (id of ids) {}でループさせる
3. appendを使ってdivのなかに取ってきた情報を表示させる。

# チャプター７　トランザクションの送信
## 要点
**callと違う点**
1. sendを使う場合トランザクションを送信するアドレスが必要。よってユーザーにトランザクションへの署名を要求するようMetamaskがポップアップする。
2. sendする場合ガス代がかかる
3. ユーザーがトランザクションをsendしてから、それが実際にブロックチェーン上で有効になるまでにはかなりの遅れがある
Metamaskを使ってWeb3.jsでこの関数を呼び出す例。

```js
function createRandomZombie(name) {
  // しばらく時間がかかるので、UIを更新してユーザーに
  // トランザクションが送信されたことを知らせる
  $("#txStatus").text("Creating new zombie on the blockchain. This may take a while...");
  // トランザクションをコントラクトに送信する:
  return cryptoZombies.methods.createRandomZombie(name)
  .send({ from: userAccount })
  .on("receipt", function(receipt) {
    $("#txStatus").text("Successfully created " + name + "!");
    // トランザクションがブロックチェーンに取り込まれた。UIをアップデートしよう
    getZombiesByOwner(userAccount).then(displayZombies);
  })
  .on("error", function(error) {
    // トランザクションが失敗したことをユーザーに通知するために何かを行う
    $("#txStatus").text(error);
  });
}
```

## 今回したこと(テスト)
上のコードみたいなやつみたいにcreateRandomZombie(ゾンビ作るやつ)と feedOnKitty (キティを捕食するやつ)を実装。

# チャプター８ Payable関数の呼び出し
**payable関数の簡単な復習**
Etherを受け取ることができる特別なタイプの関数を作るときに記述する。
## 要点
関数と併せてEtherを送信するのはシンプルだが、いくら送信するかをEtherではなくweiで指定しなくてはならない。
**Wei**
weiとはEtherの最小単位で、1 etherは10^18 weiである。

```js
web3js.utils.toWei("1", "ether");
```
これでetherをweiに変換可能。

## 今回やったこと(テスト)
levelUp関数を追加。このとき"0.001" EtherをtoWeiに変換して送信。

# チャプター9 Eventのサブスクライブ
## 要点

```js
cryptoZombies.events.NewZombie()
.on("data", function(event) {
  let zombie = event.returnValues;
  // `event.returnValues`オブジェクトのこのイベントの戻り値３つにアクセスできる:
  console.log("A new zombie was born!", zombie.zombieId, zombie.name, zombie.dna);
}).on("error", console.error);
```
これだとDApp内でゾンビが作成されるたびに通知が表示されてしまう。自分のゾンビを作った時だけ通知されるようにしたい。

**indexed**

```
event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
```
このように引数にindexedをつけておくとフロントエンド側で呼び出すときにフィルターをかけることができる。
(例)

```js
cryptoZombies.events.Transfer({ filter: { _to: userAccount } })
.on("data", function(event) {
  let data = event.returnValues;
}).on("error", console.error);
```
このように書くと_toがuserAccountの時だけ通知してくれる。
**過去イベントのクエリ**
我々はgetPastEventsを使って過去のイベントをクエリすることや、fromBlock及びtoBlockのフィルターを使用してSolidityに期間を指定してイベントのログを取ることが可能である。

```js
cryptoZombies.getPastEvents("NewZombie", { fromBlock: 0, toBlock: "latest" })
.then(function(events) {
  // `events`は、上でやったように反復可能な`event`配列内のオブジェクトである
  // このコードは、これまで生成された全ゾンビのリストを提供してくれる
});
```
## 今回したこと(テスト)
1. cryptoZombies.events.Transferをリッスンするコードブロック追加。
2. UI更新のコードを追加
これで現在のユーザーが新たなゾンビを受け取ったときにUIが更新される。

# まとめ
これで一通り終わりました。今までの記事はクリプトゾンビの要点だったりテストだったりをざっくりまとめたものなのでcryptozombieを一緒に進めている前提で書いています。おそらく記事だけ見ても何言ってるか分からないです。急いで書いたので分かりにくいかと思います。すみません。
これだけではdappsを作れないと思うのでまたdappsについて勉強したらまとめていきます。