Hardhat × Next.js × Copilot で 1 週間——最小構成の投票 DApp を作って得た学び
2025/06/07 公開
デモ
作成した DApp は下記から試すことができます。Metamask で接続後、「Option A」または「Option B」を選択するとトランザクションが確定し、結果が即時に反映される仕組みです。
https://vote-dapp-sage.vercel.app/
TOP画面
投票画面(投票前)
投票画面(投票後)
投票結果画面
なぜ作ったか
- スマートコントラクト〜フロントエンド〜デプロイを1人で全部やってみたかった。
- GPT に「投票アプリを作ってみれば?」と提案されて興味を持った。
- ポートフォリオとしても使えるようにしたいため。
実装は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 & Hosting | Hardhat 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 開発の経験を積んでみたいと感じています。
ここまで読んでいただきありがとうございました。
関連リンク