Complete deployment procedures and network configuration for production environments
This guide covers the complete deployment process for the Bet0x Protocol smart contracts, from local testing to production deployment on Arbitrum and other networks.
Setup and testing environment
Deploy and verify on testnets
Mainnet deployment and monitoring
git clone <repository-url> cd bet-protocol/contracts npm install # or pnpm install
Create .env
file:
# Network Configuration ARBITRUM_RPC_URL=https://arb1.arbitrum.io/rpc ARBITRUM_SEPOLIA_RPC_URL=https://sepolia-rollup.arbitrum.io/rpc ETHEREUM_RPC_URL=https://mainnet.infura.io/v3/YOUR_KEY # Deployment Keys (NEVER commit to git) DEPLOYER_PRIVATE_KEY=your_private_key_here ADMIN_PRIVATE_KEY=your_admin_private_key_here # Verification Keys ARBISCAN_API_KEY=your_arbiscan_api_key ETHERSCAN_API_KEY=your_etherscan_api_key # Protocol Configuration PLATFORM_FEE_RATE=250 # 2.5% TREASURY_ADDRESS=0x... INITIAL_ADMIN_ADDRESS=0x...
# Run all tests npx hardhat test # Run specific test file npx hardhat test test/BettingCore.test.ts # Run tests with gas reporting REPORT_GAS=true npx hardhat test # Run tests with coverage npx hardhat coverage
Create scripts/deploy.ts
:
import { ethers } from "hardhat"; async function main() { console.log("š Starting Bet0x Protocol deployment..."); const [deployer] = await ethers.getSigners(); const network = await ethers.provider.getNetwork(); console.log("Deploying with account:", deployer.address); console.log("Network:", network.name); console.log("Chain ID:", network.chainId); // 1. Deploy DiamondCutFacet console.log("\nš¦ Deploying DiamondCutFacet..."); const DiamondCutFacet = await ethers.getContractFactory("DiamondCutFacet"); const diamondCutFacet = await DiamondCutFacet.deploy(); await diamondCutFacet.deployed(); console.log("ā DiamondCutFacet deployed to:", diamondCutFacet.address); // 2. Deploy Diamond console.log("\nš Deploying Diamond..."); const Diamond = await ethers.getContractFactory("Diamond"); const diamond = await Diamond.deploy(deployer.address, diamondCutFacet.address); await diamond.deployed(); console.log("ā Diamond deployed to:", diamond.address); // Continue with other facets... console.log("\nš Deployment completed successfully!"); console.log("Diamond address:", diamond.address); } main() .then(() => process.exit(0)) .catch((error) => { console.error("ā Deployment failed:", error); process.exit(1); });
Create scripts/verify.ts
:
import { run } from "hardhat"; async function main() { const network = process.env.HARDHAT_NETWORK || "arbitrum"; const deployment = JSON.parse(readFileSync(`deployments/${network}-latest.json`, "utf8")); console.log("š Verifying contracts on", network); const contracts = [ { name: "DiamondCutFacet", address: deployment.diamondCutFacet, args: [] }, { name: "Diamond", address: deployment.diamond, args: [deployment.deployerAddress, deployment.diamondCutFacet] }, // Add other contracts... ]; for (const contract of contracts) { try { console.log(`Verifying ${contract.name} at ${contract.address}...`); await run("verify:verify", { address: contract.address, constructorArguments: contract.args, }); console.log(`ā ${contract.name} verified`); } catch (error) { console.log(`ā Failed to verify ${contract.name}:`, error.message); } } }
# Deploy to Arbitrum Sepolia testnet npx hardhat run scripts/deploy.ts --network arbitrumSepolia # Verify contracts npx hardhat run scripts/verify.ts --network arbitrumSepolia
# Run integration tests against testnet deployment npx hardhat test test/integration/ --network arbitrumSepolia
# Deploy to Arbitrum mainnet npx hardhat run scripts/deploy.ts --network arbitrum # Verify all contracts npx hardhat run scripts/verify.ts --network arbitrum # Transfer ownership to multi-sig npx hardhat run scripts/transfer-ownership.ts --network arbitrum
// Set up initial roles and parameters async function postDeploymentSetup(diamondAddress: string) { const diamond = await ethers.getContractAt("BettingCoreFacet", diamondAddress); // Grant oracle roles const oracleAddresses = [ "0x...", // Oracle 1 "0x...", // Oracle 2 ]; for (const oracle of oracleAddresses) { await diamond.grantRole( ethers.utils.keccak256(ethers.utils.toUtf8Bytes("ORACLE_ROLE")), oracle ); } // Set up platform parameters await diamond.setPlatformFeeRate(250); // 2.5% await diamond.setTreasury("0x..."); // Treasury address }
// Set up monitoring for critical events const monitoringEvents = [ 'EventCreated', 'BetPlaced', 'EventResolved', 'EmergencyPause', 'BlacklistAdded' ]; for (const eventName of monitoringEvents) { diamond.on(eventName, (...args) => { console.log(`Event ${eventName} detected:`, args); // Send to monitoring service sendToMonitoring(eventName, args); }); }