Web3アプリを作ったまとめ

14663 ワード

Student FacuetというDapp(Web3アプリ)を作成したら結構人気が出たので、技術面から運用面までを軽くまとめました。わかりやすくするために多少語弊がある表現ある場合がありますが、ご了承ください。
Githubリポジトリ: https://github.com/inaridiy/AStar-Student-Faucet

自己紹介

所属の というものです。
Web歴は2年、Web3歴は3ヶ月の高校2年生です。普段はハッカソンに出たり、個人開発をしています。

Faucetとは

現状、ブロックチェーン間で資産を移動させたい場合、移動元のガス代と移動先のガス代がかかります。つまり、資産を動かす前に移動したいチェーンの通貨が必要になります。
これはかなりUXを損なう行為ですし、仮想通貨取引所を開設できない未成年などは、そもそも資産を移動することができないような事態も起こり得ます。
これを緩和するためにチェーン側がFaucetという機能を提供していることがあります。
Faucetとは英語で蛇口を意味し、ブロックチェーンの世界ではトランサクション数回分の仮想通貨を無料で配っているサービスの名称です。
Astar NetworkでもAstar,Shiden,ShibuyaのそれぞれのチェーンにFaucet機能が提供されいてAstar Portalから利用できます。
ですが、Astar NetworkのFaucetは度々Faucet用の資金が枯渇してFaucetが使えない状態になっていました。これは上記のようにAstarを使う上でとても大きな障害になってしまっていると感じていました。

Student Faucetとは

前述の通り、Astar NetworkでFaucetが使えないので、主に学生用のFaucetを作ることにしました。
具体的には通貨を多く持っている人にFaucetをサポートしてもらって、そうして集めた資金を少しずつ配るという感じです。
それだけだとサポートしても旨味がないので、サポートしてくれた方にはジェネレイティブNFTを配っています。

コントラクトを作成、デプロイする

Student FaucetではコントラクトをOpenzeppelinのERC721Upgradebleをベースに作成しています。
OpenZepplinとはコントラクトのテンプレみたいなものを提供しているヤツです。cryptoZombieなどをやった方はERC721のコントラクトを全て手作業で実装したと思いますが、提供されているコントラクトベースにすればだいぶ楽です。
また、Student FaucetではUpgradeble Contractというものを使っており、通常、EVM系のコントラクトは機能を足したり、バグを修正したりはできませんが、それをあーだこーだすることで可能にしてくれます。
設定と概念などが面倒なので、最初の開発にはおすすめしませんが、あると便利なので軽く調べてみるといいかもしれません。
参考までに私はこちらの記事を重宝しました。

コントラクトのソースコードなどはGithubから見れるので省略します。
そしてコントラクトはHardHatでデプロイしています。HardHatはJsonRPCが提供されているEVM系のチェーンならすぐにデプロイできて便利です。

フロントエンドを作る

コントラクトだけあっても使えないので、フロントエンドも実装していきます。
フロントエンドはNext.js,TailwindCSS,Ethers.jsをベースに色々設定を追加したりしているテンプレをベースにしています。
また、スマホでも使えるようにWalletConnectとかUIフレームワークにDaisyUIとか他にも色々追加しています。
これに関しては全部触れれるとキリがないので重要そうなところを軽く紹介します。

useWeb3

コンポーネントやページなどを実装していく上でwalletなどの状態を管理することが必須となりますが、この管理を楽にするためにuseWeb3というReact Hooksを作成して運用しています。
具体的にはReact Contextという機能を用いてサイト全体でアクセスできるStateを作成しています。
もし、DAppを作りたいのでしたら、こんな感じの使いやすいHooksを作成するのがお勧めです。
これのコードは載せると長くなるのでリポジトリを参照していただければ幸いです。

TailwindCSS & DaisyUI

この二つは神です。フロントエンドの作成速度を数倍にしてくれます。
まず、TailwindCSSUtility ClassというCSSのClassがたくさん入ったCSSライブラリです。
簡単にいうと、CSSをほとんど書かずに狙ったデザインを作成できるようになります。
次にDaisyUIですが、これはTailWindCSSのプラグインで、TailwindCSSが導入されている環境なら1分で導入できます。
このプラグインはTailwindCSSにボタンやモーダルなどのいい感じのClassを追加してくれます。
脳死で収録されれいるClassを当てるだけでそれっぽいサイトが完成します。
ただ、これだけならBootstrapやMaterial-UIでもいいのですが、このDaisyUIは無茶苦茶すごい機能がついています。
それはテーマ機能です。なんと28種類のテーマが標準でついていて、作成したサイトのテーマを入れ替えるだけで、全く違う印象を与えることができます。
少し踏み込んだ話をすると、各テーマにbase,netural,primary,secondary,accentのカラーパレットが付属しており、それらを背景色にしたときに見やすいテキストの色もそれぞれbase-content,netural-content...のような感じで付属しているので本当にテーマを入れ替えるだけでいけます。

Typescript & TypeChain

先ほどの二つはデザインに関するツールでしたが、このTypescriptとTypeChainはロジックに関するツールです。
まず、TypescriptはJavascriptの変数に型という概念を追加してくれます。
これにより関数の引数などに間違った変数を突っ込むことがだいぶ減ります。
また、TypeChainを使えうとコントラクトにTypescriptの型を付与することができます。これでバグも減って入力補完も聞きます。
この二つの導入はReactやNext.jsなどの環境だと楽なので入れてみるといいかもしれません。
ですが、もしJavascriptの基礎と並列してTypescriptを使うのは絶対にお勧めしません。

Dropの内部処理とガスレス

このStudent Faucetでターゲットとなる人はガス代を持っていない人なので、ユーザーが直接トランザクションを送ることができません。
そのため、別のアドレスが代わりにコントラクトのDrop用の関数を叩いてやる必要があります。
これに関しては基本的にGas Lessのプロダクトの基本だと思います。
どうやらGSN(Gas Staion Network)というものを使う方法もあるようです。
GSNを使う方法は僕自身が学習中なので詳しいことは言えませんが、大元は最初の手段と同じだと思います。

ユーザーは自分のアドレスをWeb2的なAPIに送信し、内部で僕のFaucet用のWalletが自動的にコントラクトを叩いています。
ethers.jsにはWalletを生成する機能がついているのでそれを利用しています。
一部簡略化していますが、実際に動いているコードはこんな感じです。

pages/api/drop.ts
 const signer = new ethers.Wallet(
    process.env.PRIVATE_KEY,
    new ethers.providers.JsonRpcProvider(rpc)
  );
  const contract = StudentFaucet__factory.connect(contractAddress, signer);

  const tx = await contract.drop(
    address,
  );

Walletを生成しているところ以外はフロントエンドなどからコントラクトを叩くのと同じだと思います。
ただこれだけだと悪意あるユーザーにAPIを大量に叩枯れて資金を盗られかねないので署名とreCAPTCHAを用いて間引いています。
これに関しては次で書きます。

署名と間引き(1段階)

Walletはテキストなどのメッセージに対して署名することができ、署名とメッセージの原文を比較することで署名したWalletのアドレスを復元することができます。
署名は本人しかできないので復元したアドレスとFaucetから受け取りを希望しているアドレスを比べることで本人以外の受け取りを防ぐことができます。
これは署名の性質というより公開鍵秘密鍵という暗号化アルゴリズムの性質です。
詳しくは調べたら出てきますがかなり複雑なので一旦は上部だけ理解することをお勧めします。

reCAPTCHAと間引き(2段階目)

署名はトランザクションの時と同様Ethers.jsで行えるのでボットは防げません。そのためボットを防ぐためにreCAPTCHAというサービスを導入しています。
reCAPTCHAはGoogleが提供しているサービスでAIを用いて高精度にBOTを弾くことができます。
こちらは導入も簡単かつ記事も出回っているので詳細は省きます。

スマホからも利用できるようにする

Web3に繋ぐとき普通はMetamaskを使うと思いますが、このままだとMetamaskが導入されている環境からしか使えなくなります。
これはパソコンからのユーザーだけを対象とするなら大した問題ではありませんが、スマホからのユーザーも対象とする場合は致命的です。なぜならMetamaskブラウザはバグとUI/UXが悪い上に使用人口も少ないためです。
そこで、スマホなどからも接続できるようにWalelt Connectというライブラリを利用します。
Wallet Connectを使うとスマホやデスクトップ環境でMetamask以外のWalletからでもいい感じに接続できるようになります。
ただ、僕側のコードのミスの可能性もありますが、現状はAstarなどのチェーンでトランザクションを走らせることができていません。
ですが、署名はできるので、Student Faucetのユーザーの大部分を占める受け取る側のユーザーは問題なく使えます。
実際このStudent Faucetのアクセスはスマホとパソコンで半々といった感じでスマホ対応しておいてよかったなと思っています。

NFTの生成

Student Faucetではサポートしてくれた人に以下のようなNFTを配っています。

これはNext.jsで書かれたページをPlaywrightというヘッドレスブラウザでスクショ撮っています。
もう少し詳しく解説すると、Chromiumなどのブラウザをjavascriptなどのプログラムから操作できるようにするツールがあり、その中で個人的に気に入っているのがPlaywrightです。
ブラウザをそのまま動かせるので完璧なページのスクショが撮れますし、ユーザーの操作を再現したテストなど行うこともできます。
このPlaywrightを使ってWebページ自体のスクショを取る方法をとることで、素早くそれっぽい画像が作れるようになります。
ただ、注意点としてはこの手法では画像の生成にかなり時間がかかるのと、効率が悪いです。そのため、時間に余裕があったり複雑な表現は事前生成などができるならてnode-canvassharpなどといったライブラリで合成したほうがいいと思います。

超節約デプロイ術

サービスが完成したらデプロイしないといけない訳ですが、できるだけ節約したかったので色々と工夫しました。
結果、Student Faucetは今の所維持費がドメイン代だけで済んでいます。(大体$9/year)
具体的にはWebページをNetlifyというサービスでWebサイト自体をホスティングして、それにcloudflareをかましています。
この、超節約デプロイ方法に関しては需要があると思うので詳しく解説していきます。

ホスティングサービス

Webサービスを公開する手段と方法はいくらでもあります。
ですが、僕は楽で安いホスティングサービスというものを使うことが多いです。
もちろんAWSやGCPなどのCloudを使ったりConohaなどのVPSを使うこともできますが、複雑だったり高かったりするのでパッとサービスを公開するのには向いていないと思います。
まず、ホスティングサービスには主要なものが5個ぐらいあるのですが、特にお勧めな2種類を軽く紹介します。

Netlify

大体のフレームワークのサイトをデプロイでき、プラグインなどもあります。無料枠も大きめで商用利用化です。CLIツールとPushをトリガーにした自動デプロイもできます。
日本からのアクセスがちょっと遅いです。

Vercel

基本的にはNetlifyと同じですがNetlifyよりも何かと開発体験がいいです。
またVercel社はNext.jsを開発しているので、Next.jsとVercelの相性は抜群です。無料プランだと商用利用不可。
こちらは日本からのアクセスも速いです。

この二つにはServer Less Functionという機能がついておりSSRやNFT用の画像の自動生成もできるので、便利です。
商用利用しないならVercelをするならNetlifyをといった感じで使い分けるといいと思います。

CDNとCloudflare

ホスティングサービスだけでもWebサービスは公開できるのですが、サービスがバズったりすると無料枠を超えたりします。
それを防ぐべくCDNという仕組みを使って帯域幅を節約します。CDNについては詳しく解説しませんが、世界中のサーバーでサイトのデータをキャッシュしてくれます。

CDNを提供しているサービスにはいくつかあるのですが、中でもCloudflareが最強です。
無料枠が限りなく大きく、導入も簡単で、しかもCDN以外にもさまざまな最適化を施してくれます。
また、Cloudflareではドメインも取得することができます。
例えばお◯前.comなどでは初年は1円でも2年目以降に莫大なお金がかかります。詐欺だと思う
しかしCloudflareなら毎年一定の値段で、しかも安くドメインを購入できます。
他にも設定不要でアクセス解析ができたりもするので、Cloudflareは導入すべきです。

節約術番外編

Student Faucetでは利用しませんでしたが、他にも節約の味方になり得るサービスがいくつかあるので紹介しておきます。

Firebase

色々と便利なmBaasです。 Webサイトのホスティングや認証、データベースなどをまとめて提供してくれます。かなり手軽に使うことができ、無料枠もあります。
無料枠はバズったりするとすぐなくなる量ですが、他サービスと違って使った分だけ課金されるので便利です。

PlanetScale

ServerLessDBというやつらしくてSQLのデータベースを簡単に作成できます。無料枠もかなり大きいので便利だと思います。

アクセス分析

サービスを公開したら、どれだけの人がどこからアクセスしてくれているのかが気になるのが人の常だと思います。
Student FuacetではCloudflare Analytics,Google Analytics,Google Search Consoleなどを使ってアクセス分析を行なっています。

ツール紹介

Cloudflare Analytics

Cloudflareを使っていると設定不要でみれる便利なツールです。
世界各国からのアクセス数  、リクエスト数、帯域幅を一時間刻みで見ることができます。
設定不要で使える分、かなり簡易的な表示しかできませんが、アクセス数を見てニヤニヤする分には十分です。

Google Analytics

王道の解析ツールです。少し設定が面倒ですが、いろいろな情報を見ることができます。
このツールは本当に多機能すぎて本が出ているぐらいなので詳しくは触れきれませんが、リアルタイムにどこからアクセスされているかや、ユーザーの端末などなど色々見えます。
注意点としてはGDPRというクソセキュリティに関する条約を守らないといけなるなるため、Google Analyticsとは別に対応をする必要があります。
しかし、リアルタイムで世界中のユーザーがアクセスしてくいるのを見れるので、ニヤニヤできます。

Next.jsの場合、最低限_document.tsxなどのファイルに下のように設定を書き足せば使えるようになります

_document.tsx

      ...
      <Head>
      ...
       <script
              async
              src={`https://www.googletagmanager.com/gtag/js?id="ここにトラッキングID"}
            />
            <script
              dangerouslySetInnerHTML={{
                __html: `
                    window.dataLayer = window.dataLayer || [];
                    function gtag(){dataLayer.push(arguments);}
                    gtag('js', new Date());
                    gtag('config', 'ここにもトラッキングID');
                  `,
              }}
            />
     ...

Google Search Console

Google検索から何人アクセスされたのか、どこのサイトにリンクが貼られているかなどのインターネット上でのサイトの見え方を分析できることができます。
また、Google Analyticsと連携などもできます。

こちらはCloudflareのDNSの設定にGoogle Search Consoleから渡されたレコードを書き足せばOKです。

Student Faucetのアクセス状況


この画像はGoogle Analyticsの情報の一部なのですが、見ての通り圧倒的にインドネシアからのアクセスが多いです。
インドネシアではブロックチェーンが活発なのか、それとも別の要因があるのか...
他にもロシアからのアクセスも多いのですが、その原因の一端がわかるのが次の画像です。

この画像はStudent Faucetへのリンクを貼っているサイト一覧ですが、teletypeというサイトが多いと思います。
調べてみたところ、teletypeはロシアなどで使われている情報サイトらしく、そこで多く紹介されたためにロシアからのアクセスも増えたと予想しています。

お小遣い稼ぎ

Student Faucet折角たくさんアクセスされているのでってことで、欲を出して広告をつけています。
広告サービスには王道のGoogle Adsenseを使っていて結構嬉しい額が入ってきています。
毎日額がかなり異なるので、なんとも言い得ませんが、三日でサービスの維持費が賄えるぐらいです。
Google Adsenseは審査が必要なのでハードルは高いですが、サービスの維持に回せるぐらいの収入が入るので、サービスを公開したら申請してみるといいかもしれません。

こちらも申請さえ通れば軽く設定を追加するだけでGoogle側でよしなにやってくれます。

終わりに

かなり自分語り的な記事でしたが、読んでくださりありがとうございます。もし何かわからないところなどがございましたら、TwitterなどでDMをくださればお答えします。
また、最後にMatic Student Faucetが現在枯渇しており、使えない状態です。
1Maticで125人分賄えるので、もしよければこのページからサポートをお願いします。