CI/CD untuk Smart Contract — Testing, Regresi Gas, dan Keamanan
Engineering Team
Mengapa CI/CD untuk Smart Contract
Smart contract tidak bisa diupdate setelah deployment — bug yang lolos ke mainnet bisa menyebabkan kerugian dana yang tidak dapat dipulihkan. CI/CD pipeline yang ketat adalah pertahanan terakhir sebelum kode mencapai blockchain.
Pipeline Overview
commit → lint → compile → unit test → fuzz test → gas check → security → deploy
Setiap tahap harus lulus sebelum melanjutkan. Satu kegagalan menghentikan pipeline.
GitHub Actions Workflow
name: Smart Contract CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Compile
run: forge build --sizes
- name: Unit Tests
run: forge test -vvv
- name: Fuzz Tests
run: forge test --match-test testFuzz -vvv --fuzz-runs 10000
- name: Gas Snapshot
run: |
forge snapshot
forge snapshot --diff --check --tolerance 5
Penjelasan Tahap
-
Compile —
forge build --sizesmengkompilasi dan melaporkan ukuran bytecode. Kontrak yang melebihi 24KB (batas EIP-170) gagal. -
Unit Tests — Semua test standar dengan verbosity level 3 untuk trace pada kegagalan.
-
Fuzz Tests — Test khusus fuzzing dengan 10.000 iterasi. Jalankan terpisah karena memakan waktu lebih lama.
-
Gas Snapshot — Bandingkan gas saat ini dengan snapshot tersimpan. Toleransi 5% mengizinkan variasi kecil.
Gas Regression Check
Gas snapshot adalah file yang melacak biaya gas per test:
# File: .gas-snapshot
testSwapExactIn() (gas: 72543)
testTransfer() (gas: 24123)
testMultiHopSwap() (gas: 145678)
Dalam CI:
- name: Gas Check
run: |
forge snapshot --snap .gas-snapshot-new
# Bandingkan dan gagalkan jika ada regresi > 5%
python scripts/check_gas_regression.py \
.gas-snapshot .gas-snapshot-new 5
Script Python membandingkan setiap entri dan menghitung persentase perubahan.
Analisis Keamanan Statis
Slither
- name: Slither Analysis
run: |
pip install slither-analyzer
slither . --config-file slither.config.json
Slither mendeteksi kerentanan umum: reentrancy, unchecked return value, shadow variable, dan lainnya.
Mythril
- name: Mythril
run: |
docker run -v $PWD:/code mythril/myth analyze /code/src/Contract.sol
Mythril menggunakan symbolic execution untuk menemukan kerentanan yang lebih dalam.
Deployment Otomatis
deploy:
needs: [test]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Deploy to Testnet
run: |
forge script script/Deploy.s.sol \
--rpc-url $TESTNET_RPC \
--broadcast \
--verify
env:
PRIVATE_KEY: ${{ secrets.DEPLOYER_KEY }}
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_KEY }}
Script Deployment Foundry
contract Deploy is Script {
function run() external {
vm.startBroadcast();
MyContract contract = new MyContract();
console.log("Deployed at:", address(contract));
// Verifikasi constructor
assertEq(contract.owner(), msg.sender);
vm.stopBroadcast();
}
}
Pre-commit Hook
#!/bin/bash
# .git/hooks/pre-commit
set -e
forge fmt --check
forge build
forge test --match-test testUnit -q
forge snapshot --diff --check --tolerance 2
Monitoring Post-Deployment
CI/CD tidak berakhir di deployment. Monitor kontrak di produksi:
- Event monitoring — Pantau event mencurigakan (transfer besar, ownership change)
- Balance tracking — Alert jika saldo kontrak turun tidak terduga
- Gas usage — Lacak rata-rata gas per fungsi
- Revert rate — Alert jika persentase revert meningkat
Kesimpulan
CI/CD untuk smart contract bukan opsional — ini adalah keharusan. Pipeline yang mencakup unit test, fuzz test, gas regression, analisis keamanan statis, dan deployment otomatis menciptakan pertahanan berlapis terhadap bug yang bisa menjadi bencana keuangan.