Hardhat × Next.js × Copilot で 1 週間——最小構成の投票 DApp を作って得た学び

Hardhat × Next.js × Copilot で 1 週間——最小構成の投票 DApp を作って得た学び

2025/06/07 公開

デモ

作成した DApp は下記から試すことができます。Metamask で接続後、「Option A」または「Option B」を選択するとトランザクションが確定し、結果が即時に反映される仕組みです。
https://vote-dapp-sage.vercel.app/

TOP画面

投票画面(投票前)

投票画面(投票後)

投票結果画面

なぜ作ったか

  1. スマートコントラクト〜フロントエンド〜デプロイを1人で全部やってみたかった。
  2. GPT に「投票アプリを作ってみれば?」と提案されて興味を持った。
  3. ポートフォリオとしても使えるようにしたいため。

実装はGitHub Copilot Agent(モデル: Claude Sonnet 4)にissueの内容を渡して実装してもらい足りないところは補うようにしました。
デザインは Google Stitch で生成した UI を使い色やマージンは後で微調整しています。

技術スタック

レイヤ技術
フロントエンドNext.js 15 / React 19 (React Compiler) / Tailwind CSS / shadcn/ui
UI デザインGoogle Stitch 生成
スマートコントラクトSolidity 0.8.28 (Hardhat)
ネットワークSepolia テストネット(Infura RPC)
CI/CD & HostingHardhat scripts / Vercel

開発フロー

手順ざっくり内容
Issue 設計GitHub Projects でタスクを細分化。「一人開発でも迷子にならない」を実感。
コーディングCopilot Agentで8割実装→必要最低限の修正を加えてコミット。
テストHardhatのローカルチェーンで動作確認。主要分岐をスクリプト化して再実行しやすく。
デプロイSepoliaにコントラクト → Vercelにフロントを配置。

設計方針(最小構成)

1 人 1 票の担保

mapping(address ⇒ bool) public voted; で同一アドレスの二重投票を防止しています。

二択に限定

// 投票オプション:A または B string[2] public options = ["A", "B"];

ロジックを極力シンプルにしています。

投票内容はハードコード

学習目的のため、フロント側に直接ベタ書きしました(改善予定)。

得られた気づき

  • 資金の流れが見える化された
    ETHの取り扱いやガス代がどうかかってくるのか実感できました。特に誤ってHardhatのテストアカウントのMainnetに送金してしまった事故は教訓になりました。

  • ethers.jsは直感的で使いやすい
    web3.jsは使ったことないので比較とかはできないのですが、BrowserProvider → getSigner()のシンプルな流れで容易に署名まで完了できました。

  • テストETHの取得が面倒だった
    Sepolia Faucetは0.001ETH以上ではありますが、Mainnet ETHが必要になるなど、予想外の手間が発生しました。コミュニティに入ってるとテスト資金もらえたりするのでしょうか...

  • AIによる開発効率化が顕著
    Copilot Agent を活用することで8割の作業が自動化され、個人開発のハードルが大幅に下がったと感じました。
    デザインもこういう感じで作って欲しいというとStitchがかなり良いデザインで作ってくれて助かりました。

  • 投票結果が一時的にズレて表示された問題
    開発中、OptionAに2つ投票したはずなのに、表示上は A:1 / B:1 になる謎の挙動に遭遇しました。コントラクトへの送信内容は正しかったものの、Metamaskのネットワーク接続が不安定だったようで、再接続したら正しい投票数が表示されました。RPC側のキャッシュや同期ズレはかなり混乱しました。。

今後の改善計画

  • 投票内容の動的化

今回は投票内容をA、Bベタで入れているだけなので、CMS管理して投票内容を変更できるようにしたいです。

  • ウォレット UX の低負荷化

実装してみて、Metamaskの導入だったりETHが必要になるなど一般ユーザーにとってDAppはかなりハードル難くなりそうな印象を受けました。ソーシャルログインだったりと簡単に認証できないか検証してみたいです。

  • wagmi+WalletConnectによるモバイル対応
    現状はwindow.ethereumに依存しているため、スマホブラウザではMetaMaskがインストールされていないと動作せず、エラーが発生してしまいます。次回以降はwagmi + WalletConnectを導入し、スマホでもウォレット接続に対応できるよう改善したいです。

まとめ

オンチェーン投票アプリの実装を通して、Web3 開発のリアルな側面を体感できました。
実装そのものは AI のサポートでかなりスムーズに進みましたが、テスト ETH の取得など細かいところでつまづく場面もありました。

それでも一人で作り切ったという達成感は大きく、今後は何かしら実務でも Web3 開発の経験を積んでみたいと感じています。

ここまで読んでいただきありがとうございました。

関連リンク

Hardhat × Next.js × Copilot で 1 週間——最小構成の投票 DApp を作って得た学び