Deployment Guide
Deploy Opacus Protocol smart contracts to 0G Chain testnet and mainnet.
Prerequisites
✅
Node.js: v18 or higher
✅
Hardhat: Installed globally or locally
✅
0G Tokens: For gas fees (testnet or mainnet)
✅
Private Key: Deployment wallet with sufficient funds
Setup
1. Clone Repository
git clone https://github.com/Opacus-xyz/Opacus/opacus.git
cd opacus/contracts
2. Install Dependencies
npm install
3. Configure Environment
Create a .env file:
# Deployment wallet private key
PRIVATE_KEY=your_private_key_here
# 0G Chain RPC URLs
TESTNET_RPC_URL=https://evmrpc-testnet.0g.ai
MAINNET_RPC_URL=https://evmrpc.0g.ai
# Etherscan API key (for verification)
ETHERSCAN_API_KEY=your_etherscan_api_key
# Governance address
GOVERNANCE_ADDRESS=0x...
# Initial parameters
PROTOCOL_FEE_BPS=50 # 0.5%
MIN_STAKE_AMOUNT=1000000000000000000 # 1 0G
⚠️ Security Warning
Never commit your .env file to version control. Add it to .gitignore immediately.
Hardhat Configuration
Verify your hardhat.config.ts:
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@nomiclabs/hardhat-etherscan";
import "dotenv/config";
const config: HardhatUserConfig = {
solidity: {
version: "0.8.20",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
},
networks: {
testnet: {
url: process.env.TESTNET_RPC_URL,
accounts: [process.env.PRIVATE_KEY!],
chainId: 16600,
gasPrice: 1000000000 // 1 gwei
},
mainnet: {
url: process.env.MAINNET_RPC_URL,
accounts: [process.env.PRIVATE_KEY!],
chainId: 16601,
gasPrice: 2000000000 // 2 gwei
}
},
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY
}
};
export default config;
Compilation
# Compile all contracts
npx hardhat compile
# Clean and recompile
npx hardhat clean && npx hardhat compile
# Check for compilation warnings
npx hardhat compile --show-stack-traces
Testing
Run comprehensive tests before deployment:
# Run all tests
npx hardhat test
# Run specific test file
npx hardhat test test/OpacusCore.test.ts
# Run with gas reporting
REPORT_GAS=true npx hardhat test
# Run with coverage
npx hardhat coverage
✅ Test Coverage Target
Aim for >90% test coverage before deploying to mainnet. All critical paths should be tested.
Deployment Script
Create scripts/deploy.ts:
import { ethers } from "hardhat";
async function main() {
console.log("🚀 Starting Opacus Protocol deployment...\n");
const [deployer] = await ethers.getSigners();
console.log("Deploying with account:", deployer.address);
const balance = await ethers.provider.getBalance(deployer.address);
console.log("Account balance:", ethers.formatEther(balance), "0G\n");
// 1. Deploy AgentRegistry
console.log("📝 Deploying AgentRegistry...");
const AgentRegistry = await ethers.getContractFactory("AgentRegistry");
const agentRegistry = await AgentRegistry.deploy();
await agentRegistry.waitForDeployment();
const agentRegistryAddress = await agentRegistry.getAddress();
console.log("✅ AgentRegistry deployed:", agentRegistryAddress, "\n");
// 2. Deploy DACRegistry
console.log("📝 Deploying DACRegistry...");
const DACRegistry = await ethers.getContractFactory("DACRegistry");
const dacRegistry = await DACRegistry.deploy(agentRegistryAddress);
await dacRegistry.waitForDeployment();
const dacRegistryAddress = await dacRegistry.getAddress();
console.log("✅ DACRegistry deployed:", dacRegistryAddress, "\n");
// 3. Deploy DataStream
console.log("📝 Deploying DataStream...");
const DataStream = await ethers.getContractFactory("DataStream");
const dataStream = await DataStream.deploy(agentRegistryAddress);
await dataStream.waitForDeployment();
const dataStreamAddress = await dataStream.getAddress();
console.log("✅ DataStream deployed:", dataStreamAddress, "\n");
// 4. Deploy MsgEscrow
console.log("📝 Deploying MsgEscrow...");
const MsgEscrow = await ethers.getContractFactory("MsgEscrow");
const msgEscrow = await MsgEscrow.deploy(agentRegistryAddress);
await msgEscrow.waitForDeployment();
const msgEscrowAddress = await msgEscrow.getAddress();
console.log("✅ MsgEscrow deployed:", msgEscrowAddress, "\n");
// 5. Deploy OpacusCore
console.log("📝 Deploying OpacusCore...");
const OpacusCore = await ethers.getContractFactory("OpacusCore");
const opacusCore = await OpacusCore.deploy();
await opacusCore.waitForDeployment();
const opacusCoreAddress = await opacusCore.getAddress();
console.log("✅ OpacusCore deployed:", opacusCoreAddress, "\n");
// 6. Initialize OpacusCore
console.log("🔧 Initializing OpacusCore...");
const governanceAddress = process.env.GOVERNANCE_ADDRESS || deployer.address;
const protocolFeeBps = parseInt(process.env.PROTOCOL_FEE_BPS || "50");
await opacusCore.initialize(
agentRegistryAddress,
dacRegistryAddress,
dataStreamAddress,
msgEscrowAddress,
governanceAddress,
protocolFeeBps
);
console.log("✅ OpacusCore initialized\n");
// 7. Set OpacusCore in other contracts
console.log("🔗 Linking contracts...");
await agentRegistry.setOpacusCore(opacusCoreAddress);
await dacRegistry.setOpacusCore(opacusCoreAddress);
await dataStream.setOpacusCore(opacusCoreAddress);
await msgEscrow.setOpacusCore(opacusCoreAddress);
console.log("✅ Contracts linked\n");
// Print deployment summary
console.log("=" .repeat(60));
console.log("📋 DEPLOYMENT SUMMARY");
console.log("=" .repeat(60));
console.log("OpacusCore: ", opacusCoreAddress);
console.log("AgentRegistry: ", agentRegistryAddress);
console.log("DACRegistry: ", dacRegistryAddress);
console.log("DataStream: ", dataStreamAddress);
console.log("MsgEscrow: ", msgEscrowAddress);
console.log("=" .repeat(60));
console.log("\n✅ Deployment complete!");
// Save addresses to file
const fs = require("fs");
const addresses = {
network: (await ethers.provider.getNetwork()).name,
chainId: (await ethers.provider.getNetwork()).chainId,
deployer: deployer.address,
timestamp: new Date().toISOString(),
contracts: {
OpacusCore: opacusCoreAddress,
AgentRegistry: agentRegistryAddress,
DACRegistry: dacRegistryAddress,
DataStream: dataStreamAddress,
MsgEscrow: msgEscrowAddress
}
};
fs.writeFileSync(
"deployments.json",
JSON.stringify(addresses, null, 2)
);
console.log("\n💾 Addresses saved to deployments.json");
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Deploy to Testnet
# Deploy to 0G testnet
npx hardhat run scripts/deploy.ts --network testnet
# Watch deployment progress
# Expected output:
# 🚀 Starting Opacus Protocol deployment...
# Deploying with account: 0x...
# Account balance: 10.5 0G
#
# 📝 Deploying AgentRegistry...
# ✅ AgentRegistry deployed: 0x...
# ...
⏱️ Deployment Time
Full deployment takes approximately 2-3 minutes on testnet. Each contract deployment requires a transaction confirmation.
Verify Contracts
Verify contracts on block explorer:
# Verify all contracts
npx hardhat verify --network testnet AGENT_REGISTRY_ADDRESS
npx hardhat verify --network testnet DAC_REGISTRY_ADDRESS AGENT_REGISTRY_ADDRESS
npx hardhat verify --network testnet DATA_STREAM_ADDRESS AGENT_REGISTRY_ADDRESS
npx hardhat verify --network testnet MSG_ESCROW_ADDRESS AGENT_REGISTRY_ADDRESS
npx hardhat verify --network testnet OPACUS_CORE_ADDRESS
# Or use verification script
npx hardhat run scripts/verify.ts --network testnet
Deploy to Mainnet
⚠️ Mainnet Deployment Checklist
- ✅ All tests passing with >90% coverage
- ✅ Contracts audited by professional security firm
- ✅ Testnet deployment tested extensively
- ✅ Governance addresses configured correctly
- ✅ Sufficient 0G tokens for deployment gas
- ✅ Backup private key stored securely
- ✅ Emergency pause mechanism tested
# Deploy to mainnet
npx hardhat run scripts/deploy.ts --network mainnet
# Verify on mainnet
npx hardhat run scripts/verify.ts --network mainnet
Post-Deployment
1. Verify Deployment
# Run post-deployment tests
npx hardhat run scripts/post-deploy-check.ts --network testnet
# Check contract states
npx hardhat console --network testnet
> const opacusCore = await ethers.getContractAt("OpacusCore", "0x...")
> await opacusCore.paused()
false
> await opacusCore.governance()
"0x..."
2. Update SDK Configuration
Update sdk/src/config.ts with new addresses:
export const CONTRACT_ADDRESSES = {
testnet: {
opacusCore: '0x...',
agentRegistry: '0x...',
dacRegistry: '0x...',
dataStream: '0x...',
msgEscrow: '0x...'
},
mainnet: {
opacusCore: '0x...',
agentRegistry: '0x...',
dacRegistry: '0x...',
dataStream: '0x...',
msgEscrow: '0x...'
}
};
3. Update Documentation
- Update contract addresses in documentation
- Update API reference with new addresses
- Publish deployment announcement
4. Monitor Deployment
# Monitor contract activity
npx hardhat run scripts/monitor.ts --network mainnet
# Set up alerts for:
# - Contract interactions
# - Gas usage spikes
# - Error events
# - Pause events
Upgrade Process
Opacus contracts use upgradeable proxy pattern:
# Deploy new implementation
npx hardhat run scripts/deploy-implementation.ts --network mainnet
# Propose upgrade (via governance)
npx hardhat run scripts/propose-upgrade.ts --network mainnet \
--implementation NEW_IMPL_ADDRESS
# After governance approval, execute upgrade
npx hardhat run scripts/execute-upgrade.ts --network mainnet
Gas Cost Estimates
| Contract | Gas Used | Cost (0G) |
|---|---|---|
AgentRegistry |
~2,000,000 | ~0.002 |
DACRegistry |
~2,500,000 | ~0.0025 |
DataStream |
~1,800,000 | ~0.0018 |
MsgEscrow |
~1,500,000 | ~0.0015 |
OpacusCore |
~3,000,000 | ~0.003 |
| Total | ~10,800,000 | ~0.0108 |
Gas prices: 1 gwei on testnet, 2 gwei on mainnet. Actual costs may vary.
Troubleshooting
Insufficient Gas
Error: insufficient funds for gas * price + value
Solution: Add more 0G tokens to deployment wallet
Nonce Too Low
Error: nonce has already been used
Solution: Clear hardhat cache or reset nonce
npx hardhat clean
Contract Size Too Large
Error: contract code size exceeds 24576 bytes
Solution: Enable optimizer in hardhat.config.ts:
optimizer: {
enabled: true,
runs: 200
}
Useful Commands
# Check contract size
npx hardhat size-contracts
# Generate ABI
npx hardhat export-abi
# Flatten contracts (for verification)
npx hardhat flatten contracts/OpacusCore.sol > flattened.sol
# Run local node (for testing)
npx hardhat node
# Deploy to local node
npx hardhat run scripts/deploy.ts --network localhost
🎉 Deployment Complete!
Your Opacus Protocol deployment is live. Next steps:
- Update SDK configuration with contract addresses
- Run integration tests against deployed contracts
- Monitor contract activity and gas usage
- Set up governance and emergency procedures
Related Documentation
- Contract Overview - Understanding all contracts
- Security Model - Security best practices
- Troubleshooting - Common issues and solutions