基于Solidity构建CTF竞赛网站的完整指南
[Web 3.0] 如何建立CTF比賽網站(Solidity)
很榮幸有機會加入DefiHackLabs台灣區的Operations並完成DEFIHACKLABS ETHEREUM AND WEB3 SECURITY BOOTCAMP。可能大家會好奇最後一天比賽網站是怎麼架設的,這邊就說明一下(開始吧):love-you_gesture:
靈感其實是來自BuidlGuidl CTF - Devcon SEA 2024的專案,連結如下:
https://github.com/BuidlGuidl/ctf.buidlguidl.com/tree/devcon-2024
BuidlGuidl提供許多腳手架可以快速架設並學習其中技術,推薦大家去學習。
1. 環境準備
- Node (>= v18.18)
- Yarn (v1 or v2+)
- Git
2. 克隆代碼庫
將檔案git clone到自己的電腦中:
git clone git@github.com:BuidlGuidl/ctf.buidlguidl.com.git
3. 項目架構解說
ctf-devcon/
└── packages/
├── hardhat/ // hardhat工具(合約存放處)
├── nextjs/ // 網頁程序
├── scripts/ // 執行script的目錄(未使用)
└── ponder/ // Ponder是區塊鏈應用後端的開源框架
使用一張圖來理解執行流程:
如上圖所示,使用Alchemy API取得訊息和Ponder來獲取自訂的區塊鏈結構資料,另外將網站部署到Vercel上。
4. 使用Hardhat部署到Holesky測試鏈
(最好具備hardhat的基礎概念)
4.1 配置hardhat.config.ts
設定相關訊息:
- providerApiKey
- deployerPrivatKey
- etherscanApiKey(非必要)
- 新增holesky networks
const providerApiKey = process.env.ALCHEMY_API_KEY // alchemy api key
const deployerPrivateKey = process.env.DEPLOYER_PRIVATE_KEY // 部署錢包的私鑰
const etherscanApiKey = process.env.ETHERSCAN_API_KEY
networks: {
holesky: {
url: `https://eth-holesky.g.alchemy.com/v2/${providerApiKey}`,
accounts: [deployerPrivateKey],
verify: {
etherscan: {
apiUrl: "https://api-holesky.etherscan.io",
apiKey: `${etherscanApiKey}`,
},
},
}
},
process.env是從.env環境變數取得,這些訊息通常不應暴露。
4.2 獲取ALCHEMY_API_KEY
- 進入 https://auth.alchemy.com/ 登入
- 進入後 apps/create new app
- 選擇chains, Activate services
紅框處就是ALCHEMY_API_KEY,Network URL也可以在這裡取得
4.3 執行script部署
檔案分布如下:
ctf-devcon/
└── packages/
├── hardhat/
├── contracts/ // 目標合約
├── deploy/ // 部署的script
└── 00_deploy_ctf_contracts.ts
對於00_deploy_ctf_contracts.ts的部分修改,如需新合約可自行添加:
// :: Challenge 2 ::
const challenge2Deployment = await deploy("Challenge2", {
from: deployer,
args: [await nftFlags.getAddress()],
log: true,
autoMine: true,
});
console.log(":triangular_flag: Challenge #2 deployed");
if (!challenge2Deployment.transactionHash) {
throw new Error("No transaction hash found for Challenge2 deployment");
}
const challenge2deploymentTx = await hre.ethers.provider.getTransaction(challenge2Deployment.transactionHash);
// 新增等待區塊5才繼續部署(如需verify則必須執行此步驟)
const challenge2receipt = await challenge2deploymentTx.wait(5);
執行以下命令,將會把abi等檔案同步到nextjs/deployedContracts.js:
yarn deploy --tags CTF --network holesky
探究yarn deploy同步原理,可研究hardhat.config.ts中的generateTsAbis:
// deploy設定之後的動作
task("deploy").setAction(async (args, hre, runSuper) => {
// 執行原始deploy任務
await runSuper(args);
// 強制執行generateTsAbis腳本
await generateTsAbis(hre);
});
5. 部署網站PONDER_URL
Ponder是區塊鏈應用後端的開源框架,可快速建立和部署API,為任何EVM區塊鏈上的智能合約提供自訂資料。我們使用https://railway.com/來部署(註冊部分省略)。
說明上圖:
- 取得新專案
- 設定環境變數
- Generate Domain(之後配置到next.js環境變數NEXT_PUBLIC_PONDER_URL)
- build完成後執行Deploy command -> yarn ponder:start
5.1 PONDER說明
查看ponder/src/Challenge1.ts和NFTFlags.ts,取其中一個檔案說明:
// 可看到利用此方式可自訂鏈上訊息,讓前端透過gql調用
// 參考packages/nextjs/app/leaderboard/page.tsx第38行
import { ponder } from "@/generated";
ponder.on("Challenge1:TeamInit", async ({ event, context }) => {
const { Team } = context.db;
await Team.upsert({
id: event.args.team,
create: {
points: 0,
sortOrder: 0n,
name: event.args.name,
size: event.args.teamSize,
updated: Number(event.block.timestamp),
},
update: {
name: event.args.name,
size: event.args.teamSize,
updated: Number(event.block.timestamp),
},
});
});
6. 設定基本資料
網站目錄在next.js,主要設定scaffold.config:
const scaffoldConfig = {
// DApp運行的網絡
targetNetworks: [chains.holesky], // 目標網絡
// indexer的startBlock
startBlock: 3167275, // 開始的block(必須設定否則無資料)
// 前端輪詢RPC服務器獲取新數據的間隔
// 如僅針對本地網絡則無效(默認4000)
pollingInterval: 10000, // 獲取新資料的間隔時間
// 這是我們的Alchemy默認API密鑰
// 您可以在https://dashboard.alchemyapi.io獲取自己的密鑰
// 建議存儲在環境變量中:
// .env.local用於本地測試,Vercel/system env config用於實時應用
alchemyApiKey: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY,
// 這是我們的WalletConnect默認項目ID
// 您可以在https://cloud.walletconnect.com獲取自己的ID
// 建議存儲在環境變量中:
// .env.local用於本地測試,Vercel/system env config用於實時應用
walletConnectProjectId: process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID,
// 僅在hardhat網絡上顯示Burner Wallet
onlyLocalBurnerWallet: true,
} as const satisfies ScaffoldConfig;
6-1. 使用Vercel部署網站
- Add New
- import project
- select framework
- setting env
部署完畢後會有這個畫面:
恭喜你部署成功 :star-struck:
可以參考:https://ctf-devcon.vercel.app/
分享當天比賽的畫面 :grinning_face_with_smiling_eyes:
簡單記錄一下希望對大家有幫助,我們下次見啦 :waving_hand:
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
公众号二维码