Day7:本番・L2デプロイ/Etherscan検証/手動承認付きCI
| ← 目次 | 前: Day6 | 次: Day8 |
学習目的
- 少額でMainnetまたはL2に安全にデプロイする流れを、手順として実行できるようになる。
- ソース検証(Verify)と成果の可観測性を確保し、Explorerで確認できるようになる。
- GitHub Actionsに手動承認ゲートを設け、誤デプロイを防げるようになる。
まず
docs/curriculum/index.mdの「共通の前提」を確認してから進める。
0. 前提
- Hardhat構成はDay3までに完了。
.envに鍵とRPCを設定し、秘密情報はGitにコミットしない。- 先に読む付録:
docs/appendix/verify.md/docs/appendix/ci-github-actions.md - 触るファイル(主なもの):
scripts/deploy-generic.ts/.github/workflows/deploy.yml/docs/DEPLOYMENTS.md/hardhat.config.ts(任意) - 今回触らないこと:いきなり多額で本番デプロイ(まずは少額・段階的に進める)
- 最短手順(迷ったらここ):1章の
deploy-generic.tsで少額デプロイ → 2章でVerify(任意)→ 4章で手動承認付きCIの要点を確認
.env.example
SEPOLIA_RPC_URL=
MAINNET_RPC_URL=
OPTIMISM_RPC_URL=
PRIVATE_KEY=0x...
ETHERSCAN_API_KEY=
OPTIMISTIC_ETHERSCAN_API_KEY=
1. デプロイスクリプトの汎用化
scripts/deploy-generic.ts
import { ethers, network } from "hardhat";
// デプロイ対象とコンストラクタ引数は環境変数で指定可能
// 例: CONTRACT=MyToken ARGS="100000000000000000000" npx hardhat run ...
async function main(){
const name = process.env.CONTRACT || "Lock";
const args = (process.env.ARGS||"").split(" ").filter(Boolean);
console.log("network:", network.name, "contract:", name, "args:", args);
const F = await ethers.getContractFactory(name);
const c = await F.deploy(...(args as any));
await c.waitForDeployment();
console.log("deployed:", await c.getAddress());
}
main().catch((e)=>{console.error(e);process.exit(1)});
実行例(MainnetにLockを小額で)
npx hardhat run scripts/deploy-generic.ts --network mainnet
実行例(OptimismにERC20を供給量指定で)
CONTRACT=MyToken ARGS=1000000000000000000000000 \
npx hardhat run scripts/deploy-generic.ts --network optimism
2. Verify(ソース検証)
Hardhat Verifyプラグインを導入(Day5参照)。
コマンド例(Mainnet:Lock)
npx hardhat verify --network mainnet <DEPLOYED_ADDR> 3600
コマンド例(Optimism:MyToken)
npx hardhat verify --network optimism <DEPLOYED_ADDR> 1000000000000000000000000
L2ごとにAPIキーが異なる。Blockscout系エクスプローラを使うチェーンでは別途設定が必要。つまずいたら
docs/appendix/verify.mdの「最短成功ルート」→「失敗時の切り分けルート」→「よくあるエラー表」を参照する。
3. リスクを下げる運用チェックリスト
- 少額デプロイで動作確認後に本量を配布。
onlyOwnerや役割権限(AccessControl)を最小権限で発行。- 緊急停止(
Pausable)や引当金上限などのセーフティガードを有効化。 - マルチシグ(Safe等)で管理鍵を保管。単独鍵は避ける。
- ソース検証(Verify) を実施し、アドレス・ABI・TxHashをREADMEに残す。
- すべての機能に単体テストとカバレッジ(Day6)を要求。
4. GitHub Actions:手動承認付きデプロイ
4.1 環境(Environment)で承認者を設定
GitHub > Settings > Environments > production を作成し、Required reviewers に承認者を登録。Secrets もここに保存。
PRODUCTION_MAINNET_RPC_URLPRODUCTION_OPTIMISM_RPC_URLPRODUCTION_PRIVATE_KEYETHERSCAN_API_KEYOPTIMISTIC_ETHERSCAN_API_KEY
4.2 ワークフロー(手動トリガ + 承認ゲート)
このリポジトリでは .github/workflows/deploy.yml を同梱している。必要に応じて編集する。
.github/workflows/deploy.yml を開いて確認する。
ポイント:
workflow_dispatchでnetwork/contract/argsを受け取る。environment: productionにより、実行前にGitHub上での人間承認が必須になる。- Secrets を
hardhat.config.tsが参照する環境変数名(MAINNET_RPC_URL/OPTIMISM_RPC_URLなど)に揃えて渡す。
承認が出ない/Secretsが読めない等で詰まったら
docs/appendix/ci-github-actions.mdの「最短成功ルート」→「失敗時の切り分け」→「よくあるエラー表」を参照する。
5. デプロイ前後のドキュメント化
docs/DEPLOYMENTS.md(同梱。追記して使う)
# Deployments
## 例:2025-11-02 mainnet MyToken v1.0.0
- contract: MyToken
- network: mainnet
- address: 0x....
- txHash: 0x....
- compiler: 0.8.24
- verified: etherscan ✅
- owner: Gnosis Safe(2/3) 0x....
- notes: 初期供給 1,000,000 MTK
6. 本番デプロイ手順(最小)
- 小額でL2(例:Optimism)へ先行デプロイ。
- Etherscan/BlockscoutでVerify。
- DApp・サブグラフ・モニタを接続して動作確認(Day10以降)。
- Mainnetに本デプロイ。
docs/DEPLOYMENTS.mdを更新し、リリースタグを付与する。
7. つまずきポイント
| 症状 | 原因 | 対処 |
|—|—|—|
| insufficient funds | 手数料不足 | 少額ETHを補充。maxFee確認 |
| nonce too low | ノンス衝突 | --networkとアカウントの送信履歴を確認 |
| Verify失敗 | コンパイラ設定不一致/引数違い | hardhat.config.tsの設定と引数を合わせる。詰まったら docs/appendix/verify.md |
| 承認が出ない | Environment reviewers未設定 | Settings > Environments を再確認。詰まったら docs/appendix/ci-github-actions.md |
8. まとめ
- デプロイをスクリプト化し、対象コントラクトと引数を環境変数で切り替えられる形にした。
- Verify と
docs/DEPLOYMENTS.mdにより、アドレスと根拠(TxHash/設定)を後から追える状態を作った。 - GitHub Actions に手動承認ゲートを入れ、誤デプロイを防ぐ運用の入口を整えた。
理解チェック(3問)
- Q1. デプロイスクリプトを「汎用化」する狙いは何か?(手動操作との比較で)
- Q2.
docs/DEPLOYMENTS.mdに残すべき情報を3つ挙げる(Verify/再現の観点で)。 - Q3. GitHub Actions の手動承認ゲートは、どんな事故を防ぐための仕組みか?
解答例(短く)
- A1. 同じ手順を安全に繰り返せるようにし、引数や対象コントラクトの差し替えも明示できる。人手によるミス(ネットワーク違い、引数違い等)を減らす。
- A2. 例:network/chainId、コントラクト名とアドレス、デプロイTxHash(加えてsolc/optimizer設定があるとさらに良い)。
- A3. 誤ったブランチ/タイミングで本番やL2へデプロイしてしまう事故を減らす(人間の確認ポイントを作る)。
確認コマンド(最小)
# 要 .env(RPC/PRIVATE_KEY)。少額で。
CONTRACT=Lock ARGS=3600 npx hardhat run scripts/deploy-generic.ts --network sepolia
# 任意(Verify:要 ETHERSCAN_API_KEY とデプロイ済みアドレス)
npx hardhat verify --network sepolia <DEPLOYED_ADDR> 3600
9. 提出物
- デプロイログ一式(ネットワーク、アドレス、TxHash)
- Etherscan/BlockscoutのVerifyリンク
docs/DEPLOYMENTS.mdの追記差分- GitHub Actions実行ページのスクリーンショット(承認→完了)
10. 実行例
- 実行ログ例:
docs/reports/Day07.md