WEB3JSを使ってイーサリアム上のデータを取得する。
34歳元寿司屋が学ぶ、DAPPの作り方。
このブログは34歳の元インドのSUSHI屋が新人研修としてDAPPアプリを完成させるまでの記録の第4話です。
1. インドの寿司屋DAPPプログラマーになる (自己紹介&研修内容)
2. 環境構築編3. ホームページ作成 4. ホーム画面を作成せよ。 ←イマココ
5. ホーム画面にマイクリ トークンを表示せよ
6. マイページを作成せよ
7. マイページに自分のマイクリ トークンを表示せよ。
8. トークン発行画面
9. ERC721をデプロイせよ
10. トークン発行機能を実装せよ
11. ホーム画面とマイページにクーポンを表示せよ。
の、第4話の予定だったのですが。。。
4〜7話まで実装が終わってしまいました!!
ワーイε=ヾ(*・∀・)/
さらに、自分のマイクリ トークンを表示するだけでなく、ウォレットアドレスを指定すると、その人が持っているマイクリ トークンが表示されるます!!なんというハイスペプログラム!!俺凄い!!
絶大な自信を持ってボスに自慢にいったところ、
凄いっすねー。
となんだかいつもより優しいww
4話分一気に終わっちゃいましたー(;´Д`)y─┛~~と伝えると、、、
え、でも、これホームページとマイページがごっちゃになってません?
とか言い出しましたよ、このボス、、、
確かに、ホームページに全ての機能が含まれていて、ホームページとマイページがきっちり分かれてないんですよね。。。
さらに割とコードがしっちゃかめっちゃかでだいぶグチャッてます。
これは、コード整理するの大変そうですね〜
とかニヤケながら言い出したww
若干、ムカつきながらも、言うことはごもっともだし、こういう基本的な設計をおろそかにしてきたせいで、プログラムを覚えられなかったんだなという思いもあり、ここは言われた通りに直すことにしました!
何と言っても、ボスの命令ですし、試用期間中なのであまり強気に出るわけにも行きませんし。。。( ̄ー ̄;
ボスの言う通りに直してから、投稿しようかとか思ったのですが、ビフォーアンドアフターでどのように修正されるのかを投稿するのも一興かと思い、初心者のクソコードを晒すことにしました。
そのため、目次は以下のように変更します。
1. インドの寿司屋DAPPプログラマーになる (自己紹介&研修内容)
2. 環境構築編
3. ホームページ作成4. WEB3.jsを使ってブロックチェ上のページを取得(クソコード) ←イマココ5. ページ分け、ルーティング設定、コードの整理
6. トークン発行画面
7. ERC721をデプロイせよ
8. トークン発行機能を実装せよ
9. ホーム画面とマイページにクーポンを表示せよ。
イーサリアムとweb3js関係
イーサリアムとはみなさんんもご存知の通り、ブロックチェーン技術を使ったスマートコントラクトの一種で、取引の記録だけでなく、処理をプログラミングすることが出来ます。イーサリアムについての適当でない説明はこちらをご参照。
今回使うweb3jsはイーサリアム上のネットワークにつながっているパソコンのどれかからデータを取ってくる役割を果たします。
上図の様にweb3.jsはユーザーのPCのブラウザで実行され、イーサリアムネットワーク上のノードからデータを引っ張ってきます。この時、web3.js では、どのサービスを使って、イーサリアムネットワーク上のノード(ネットワークに繋がった端末)からデータを取ってくるか決めるのですが、今回はメタマスクを指定します。
なぜ、メタマスク?メタマスクってウォレットじゃないのと思ったのですが、実はバックエンドでINFURAというサービスと繋がっており、そこからイーサリアム上の情報を取得することが可能です。では、コーディングに取り掛かっていきたいと思います。
前回書いたアプリに、イーサリアム上から取得したデータを表示させるには、まず、web3.jsに自分のブラウザのメタマスクと接続して、うまく連携する様に設定する必要があります。
App.vue
App.vueに今回追加で実装する機能は以下の三つです。
- 入力したウォレットアドレスに紐づくアセット(マイクリ エクステンション、以下略)を表示
- 自分のアセットを表示。
ここからは説明では、コードを機能別に分けて説明していくので、全体を見たい方はこちらをご参照ください。
まずはテンプレートで、今回作るアプリの外観をコーディングします。ヘッダーとメニューのコンポーネントは前回のものを流用し、以下の赤線で囲った部分を新規で作成しました。
- 入力欄: ウォレットアドレスを入力するボタンです。
- getボタン: 1のアドレスにひもづくアセットを取得するボタンです。
- get my assetsボタン: 自分のアドレスにひもづくアセットを取得するボタンです。
web3jsを使ってアセットを取得
ここからはweb3jsを使ってマイクリ のアセットを取得するコードを書いていきます。まず、必要なライブラリをインポートして、マイクリのデータを取ってくるために値を変数に入れます。
その後web3js推奨のメタマスク情報の取得のコードを入力します。
web3.eth.Contractインスタンスを生成し、マイクリのABIにクエリーを投げれるようにします。
その後、tokenidからマイクリ エクステンショのアセット情報をhttpリクエストで取得します。今回はhttp request用のライブラリとしてaxiosを使います。(vue resourceはvuejsの推奨ライブラリではなくなったっぽいです。。)
なお、このコードは本当は別のところで定義すべき気がするんですが、ここに書かないと動かないんで今日はこのままにします。
その後、テンプレートと情報を供給する変数を定義します。何に使ってるのかわからない変数もあるんですが、動かなくなるのが怖いので今回は放置しますww
mounted: プロパティ内に毎回websiteを開いたときに表示するアセットを取得するコードを記載します。
computedプロパティー欄で、以下の二つのファンクションを定義します。1. getHisAssets()
this.walletAddressに保存されている、フォームに入力されたウォレットアドレスにひもづく、マイクリ のアセットを全て取得し、this.itemsに保存する
3. getMyAssets ()
this.walletAddressに保存されている、フォームに入力されたウォレットアドレスにひもづく、マイクリ のアセットを読み込み、this.assetsに保存する。
なお、computedとmethodsの区別ですが、引数が変わらなくても戻り値が変わる可能性のあるものはmethodsに、それ以外はcomputedに書きました。
その後、Methods:プロパティ内のファンクションを定義しました。こちらは、マイクリのABIを叩くので、引数が同じでも戻り値が変わる可能性があるため、methodsで定義しました。
- getJsonFromWalletAdderss
引数で渡されたウォレットにひもづくNFTのtokenIdを全て取得する。
Item.vueで取得したアセットを表示する。
前回の記事で作ったB-cardのテンプレートに、App.vueで取得したデータを差し込みます。
{"name": "MCH Extension: #20020322 Lv.69","description":"ExtensionName: Elite Musket\nNickname: Kar98k","image":"https://www.mycryptoheroes.net/images/extensions/2000/2002.png","attributes":{"active_skill":"Elite Shots","agi":25,"extension_name":"Elite Musket","hp":0,"id":20020322,"int":72,"lv":69,"phy":1,"rarity":"Uncommon"},"external_url":"https://www.mycryptoheroes.net/extensions/20020322","image_url":"https://www.mycryptoheroes.net/images/extensions/2000/2002.png","home_url":"https://www.mycryptoheroes.net","extra_data":{"extension_type":2002,"nickname":"Kar98k","skill_id":2018}}
上記のようなデータのjsonが取れるので、そこからはめ込みたい情報を以下のように入れていきます。
ハマったところ
16進数
なぜかマイクリのABIから帰ってくる戻り値が16進数で、それに気づかず試行錯誤して3時間くらい削られました。
Awaitについて
データが更新されない箇所があり、おかしいなーと思ったのですが、非同期通信でデータが取得される前に次の処理が始まっていることが原因でした。Asyncで宣言されているfunctionの場合、awaitをつけないと、処理が終わる前に次の処理が始まってしまうらしいです。
web3jsのバージョンの違い
ボスが参考にくれたweb3jsのコードがバージョンが古かったため、web3js 1.0.0では動きませんでした。。。。。
ウォレットアドレスの取得
ウォレットアドレスの取り方が、むずかったです。web3.eth.getAccountsで取れるはずなんですが、
myAddress = web3.eth.getAccounts()
ではダメで、.thenを使って、そのあと、配列の1個目の要素を取らないとうまくいかなかったです。。。
await web3.eth.getAccounts()
.then(function(value){myAddress=value[0]})
雑記:
更新だいぶ時間が空いてしまいました。1日でガーッとスクリプト自体は書けたんですが、そのあと、まとめるのがたいへんでした。。。もう少し、こまめに更新していきたい。。。
今日でメタップスに入社して丁度一ヶ月です。実際にコードを書いたり、ブロックチェーン技術を事業企画に落とし込む作業を繰り返した一ヶ月でした。
自分一人で本やネットで学習するのと違い、チームで動き、他業界の人と打合せながら事業計画を練っていく中で、NFTの実利用に関してかなり理解が深まりました。
明日は会社のBBQでかなり楽しみです!!実は奥さんから今月のダイエット目標が70.5kgを指定されていたのですが、さっき測ったところ72.5キロで、だいぶやばいのですが、遠慮せず食べさせていただきたいと思います。
今を去ること11日前、6月27日金曜日午後9時…..
徳地:ボス!ブログ新記事のチェックをお願いしますー。
ボス:月曜日に見ますーーー!!😑😑😑😑
(心の声:だりーな…ギリギリに持ってくんじゃねーよ…)
….
….
….
その後、今日まで僕もボスも完全に忘れていると言う…34歳のおっさんの記憶力マジで低くてやばい…
11日間と言うのはとても長く、部署のスタッフは二人増加し(そのうち紹介します。)、BBQで肉食い過ぎて体重は2キロ増え、息子に至ってはハイハイからつかまり立ちを覚える等、本当に色々なことがありました。
今後は、ボスにチェックの確認も忘れずやっていきたいと思います。
次回は、結構すぐ更新できそうなので、乞うご期待!!(←本当か?)