えんじにゃーず・ハイ

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

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

鉄は熱い内に打て

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

f:id:areph:20180630011325p:plain

cryptozombies.io

前回はこちら。※「レッスン1でやったこと」を追加しました。

40balmung.hatenablog.com

レッスン2でやったこと

  • mappingとaddress
    • ここで詰まる人が多かった
    • mappingはわかるけど、データのイメージができないというか、参照の仕方が難しい印象
  • msg.sender
    • セキュリティでとても大事な概念
    • addressを操作する場合、必ずmsg.senderで自分のアドレスか確認することが重要
  • require
    • ガード節
  • 継承
    • 同じようなロジックを別々のコントラクトにまとめて、コードを整理するときに便利だから覚えておくといいだろう。

    • よくない設計パターン
    • A is Bの時にだけ継承を使う
  • import
  • 外部ファイル読み込み時に利用
  • ストレージ vs メモリ
    • gas量に影響する
    • memoryを変更したつもりで変更されていないという現象があるので注意
  • dnaの取得
    • まず、targetDnaが16桁であることを確認せよ。targetDnaを _targetDna % dnaModulusと同様にして最後の16桁だけ取り出せば良い

    • これがわかりづらい。requireで16桁をチェックするのか、それとも16桁を取り出せばいいのか
    • 結果は後者
    • レッスン1の最後のチャプターで操作するweb3.jsのコードで
  while (dnaStr.length < 16)
    dnaStr = "0" + dnaStr // <- 16桁に不足している場合は0埋めしているので、16桁を超えている場合のみを考慮すればOK
  • internalとexternal
    • 継承を考慮した可視性の話
    • externalについては次回以降
  • 別のコントラクトを使う
  • Interface
    • Interfaceを定義して、そのInterface越しに別のスマートコントラクトを呼び出す
  • 複数の戻り値
    • 関数は複数の値を返却することができる
    • いわゆるタプル
    • returnsに定義した名前でアクセスできるとわかりやすい
    • おかげで受け取り側がローカル変数名でなくreturnsに定義している名前で受けようとしてハマる
  • 数値の下2桁を変更する
    • number % 100 で下2桁が00になるので、後は好きな2桁の数値を加算すればいい

web3.jsを触る

レッスンだとsolidityは書くがweb3.jsは参考程度に出てくるだけなのでイメージができない。ということで、実際に書いてみましょう、という流れ。

parcel

同居人がぱぱっとJSを書いて確認したいならparcelがいいっしょとおっしゃるので試してみた。

parceljs.org

インストール

yarn global add parcel-bundler

プロジェクトディレクトリを作って

yarn init -y

これで雛形ができる

parcel index.html

これで簡易webサーバが立ち上がり

Server running at http://localhost:1234

とログが出るのでアクセスすれば確認が取れる

Ropsten Test NetworkにCryptoZombiesのコントラクトをデプロイする

そういえばRopstenにコントラクトをデプロイしたことなかったなと思い、試す。

さくっとコンパイル&デプロイしたいのでRemixを活用。

Remix - Solidity IDE

  • solidityのコントラクトコードをRemixでコンパイルしabiを取得
  • Ropsten Test Networkへデプロイしアドレスを取得

web3.jsからCryptoZombiesのコントラクトを呼び出す

めっちゃハマる。しかも最終的にはMetaMaskからではコントラクトの呼び出しができずに断念。

  • abiは別jsに切り出す
  • MetaMaskのweb3.currentProviderが取得できるがaccountsが取得できない
    • どうもjsの読み込みが早すぎてaccountが取得できないので遅延させて取得で逃げる
_createZombieなどfunctionを呼び出すとエラー発生
Uncaught Error: The MetaMask Web3 object does not support synchronous methods like eth_sendTransaction without a callback parameter. See https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-client for details.

ここで断念した。jsの書き方が悪そうだけど、solidityなのかjsの問題なのか切り分けができていないのでどうしようか。

いったんテスト用にががっと書いたので、onloadのタイミングなどちゃんと書けていないのでどこかで整理する。

truffle

truffleでプロジェクトを作成しても良かった、かも。

github.com

MetaMaskの導入

Ropsten Test Networkを使う場合はMetaMaskが手っ取り早いので、導入していない人は導入する

qiita.com

GitHub

github.com

GitHub Pages

https://areph.github.io/crypto_zomibes_for_web3/

GitHub Pagesの公開方法

公開方法は3種類

  • プロジェクト名をxxxxx.ioにする
  • masterを公開
  • docsを公開

とあるので、docsを公開した

parcelのビルド

parcelのビルドではデフォルトだとdistディレクトリへ出力されるのでコマンドを修正

parcel build -d docs index.html

これでdocsへ出力される。

しかしこれだとindex.htmlからjsが読み込まれない。どうやらindex.htmlがコンパイルしたjsを取り込むさいのパスがsrc="/hogehoge.js"となってしまっている。

これも調べてみるとpublic-urlオプションを付けると相対パスになるようなので、最終的にはビルドコマンドは下記となった。

parcel build -d docs index.html --public-url ./

これでdocsに出力されたindex.htmlを開くとweb3.jsが確認できるようになる。

parcelのビルドをスクリプト

しかしこれだとビルドするごとに以前のhtmlやjsが残ってしまうので、npm scriptで毎回削除してからビルドするようにする。

package.jsonを編集

  "scripts": {
    "build": "rm -rf ./docs/* && npx parcel build -d docs index.html --public-url ./ "
  }

これでビルドする時は

npm run build

これで毎回不要なファイルを削除してビルドしてくれるようになる。

総括

16:00から23:30ぐらいまでやってた。60インチTVでみんなでわちゃわちゃ言いながら話したりコード書いたりするの楽しい。

次回

次回も鉄は熱い内に打てということで、三日後ぐらいに開催します。