えんじにゃーず・ハイ

主にエンジニアや技術情報についてつらつら書き連ねるブログです

CryptoZombies勉強会#6を開催しました

現時点では最新のレッスン

遂に最新レッスンまで追いつきました。

f:id:areph:20180630011325p:plain

ということでCryptoZombies勉強会#6を開催しました。

今回はレッスン6を進めていきます。

レッスン6でやったこと

レッスン6はSolidityではなくデプロイしたコントラクトにWebからアクセスできるようにするライブラリWeb3.jsを使用します。

これにより、WebサイトからEthereumにアクセスして情報を取得したり書き込んだりできます。

  • Web3.js
    • Ethereum Foundationが提供しているJavaScriptライブラリ
  • JavaScript
    • ブラウザ上で動作するプログラムのプログラミング言語
    • ブラウザごとに実装が異なる
    • Web上で動きを見せるには必須の言語
    • 基本的にカオスだが今一番需要があるプログラミング言語
    • 今回はローカルの環境ではなくCryptoZombiesのレッスン内で進めるが次回以降は実際にWeb3.jsを書いていきます
  • Infra
    • publicやtestネットワークのEthereumにコントラクトをデプロイする場合、本来は自前でブロックチェーンのノードとして参加する必要がある
    • ノードとして参加するには自分の環境にEthereumのノードをダウンロードする必要があり、巨大
    • これをローカルのPCに構築するのが大変ということで簡単に取り扱えるWebサービスがInfra
  • 公開鍵/秘密鍵方式
    • 公開鍵は暗号化専用鍵
      • いわゆる宝箱を閉めることだけができる鍵
    • 秘密鍵は復号化専用鍵
      • いわゆる宝箱を開けることができる鍵
    • 相手に自分の公開鍵を渡して暗号化してもらって自分へ送ってもらい、自分の秘密鍵で復号化する
    • ただ、公開鍵/秘密鍵の生成や管理が一般人にはハードルが高い
  • MetaMask
    • ChromeFirefoxのブラウザ拡張機能のウォレット
    • このツールにより秘密鍵を楽に管理することができ、またWeb3.jsを利用しているWebサイトと連携することが可能になります
    • 現状、PCでEthereumを使ったWebサービスには必須のツール、かも
    • つまりこれがないと始まらないという…ブロックチェーン界隈はこのウォレット管理がハードル要因のひとつ
    • Web3.jsでMetaMaskを使っている場合に連携するコードを記述する
  • コントラクトのデプロイ
    • コントラクトをEthereumにデプロイするとそのコントラクトのアドレスを取得することができる
    • Web3.jsでそのアドレスを指定することでコントラクトへアクセスすることが可能になる
  • コントラクトのインターフェース(ABI)
    • コントラクトをコンパイルするとそのコントラクトにアクセスするためのインターフェース情報がJSON形式で出力される
      • 例えばメソッドの名前・引数・戻り値などの情報とか
    • Web3.jsではこのABIを取り込むことでWeb3.jsからコントラクトへどのメソッドを扱えるかなどの情報を取り込むことができる
  • Web3.jsからコントラクトへのアクセスは上述した下記が必要となる
  • 上記を取り込みインスタンス化(実体化)することでJavascriptから扱えるようになる
  • Callメソッド
    • コントラクトの読み込み専用メソッドを呼び出すことができる
    • 読み込み専用とは下記のメソッド
      • view(状態変数への書き込み(トランザクション)が発生しないが参照はする)
      • pure(状態変数への参照も行わない)
  • Sendメソッド
    • コントラクトのトランザクション書き込みメソッドを呼び出すことができる
    • トランザクションを生成するため、gas手数料が発生する
    • sendするためには関数を呼び出すfromアドレスの指定が必要となる
    • Web3.js上でgasとgasPriceを設定することもできるが省略した場合はMetaMask上でgasとgasPriceをユーザーが指定することができる
  • public 状態変数へのアクセス
    • public の状態変数はgetterが自動的に生成されるためcallで呼び出すことが可能
    • ただしmappingの場合は自動でgetterが生成されないため自前でgetterメソッドを用意する必要がある
  • JavaScriptのPromise
    • Callback関数を連鎖的に呼び出せる
    • 今回の例ではCallが正常に呼び出し完了した後に別処理を実装する
  • ユーザーがMetaMaskでアカウントを切り替えたのをイベントとして監視する
    • userAccountを退避しておき、一定期間でMetaMaskで選択されたアカウントと一致しているかチェック
    • アカウントが異なればuserAccountを更新し、そのアカウントに該当するゾンビ一覧を再描画する
  • Wei
    • Etherの更に細かい単位
    • 1 Ether = 1018 wei
    • 1 wei = 0.0000000000000000001 Ether
  • payable関数にvalueとしてEtherを送る
    • payable関数にはsend関数の引数にvalueでEtherを送ることができる
    • 単位はweiなのでWeb3.jsライブラリでEtherと単位を変換する
  • Eventの監視
    • SolidityでEventを定義しておくとWeb3.jsでEventを呼び出した際にフックすることができる
    • 今回の例では新規ゾンビを作成した後にEventを呼び出すことでWeb3.js側でゾンビが作られたんだなとわかり再描画して新規ゾンビを反映することができる
    • Eventで渡す引数にindexedを指定することでWeb3.jsからフィルタリングすることができる
    • これにより自分のaddressに関するものだけを抽出することが可能
  • イベント履歴の取得
    • getPastEventsを呼び出すことで指定したブロック間で発生したEventを取得することができる
    • Solidityでは状態変数にデータを保存すると非常に高コストだが、Eventを利用することでデータを可視化することができるテクニック
    • ただしコントラクト上からはEventの履歴を参照することはできない
    • 使い方が難しいが非常に有効なテクニックとなるので覚えておきたい

総括

遂にCryptoZombiesの最新レッスンまで追いつきました。

今回のレッスンではWeb3.jsを学びましたが、実際にWeb3.jsを書いてみないとイメージがつかないと思います。こればかりはCryptoZombiesでも難しい。

そのため、次回ではTruffleを使ってDappsを作るところも勉強会として開催します。