Deployment Guide¶
Step-by-step deployment procedures for each Verdikta Dispatcher component, deployed contract addresses, environment variable configuration, and post-deployment verification.
Prerequisites¶
- Node.js (v18+) and npm
- Hardhat with
hardhat-deployand@nomicfoundation/hardhat-toolbox - Private keys for deployer accounts (two accounts recommended: deployer + oracle operator)
- LINK tokens on the target network
- VDKA tokens (Wrapped Verdikta) for oracle staking
- Infura API key for RPC access
- Etherscan/Basescan API key for contract verification (optional but recommended)
Supported Networks¶
| Network | Chain ID | LINK Token | Notes |
|---|---|---|---|
| Base Sepolia (testnet) | 84532 | 0xE4aB69C077896252FAFBD49EFD26B5D171A32410 | Primary testnet |
| Base (mainnet) | 8453 | 0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196 | Production |
| Ethereum Sepolia (testnet) | 11155111 | 0x779877A7B0D9E8603169DdbD7836e478b4624789 | Legacy testnet |
| localhost / hardhat | 31337 | N/A | Local development |
Environment Variables¶
Create a .env file in each subproject directory.
Required Variables¶
| Variable | Description | Example |
|---|---|---|
PRIVATE_KEY | Primary deployer/owner private key | fb... |
PRIVATE_KEY_2 | Secondary key (oracle operator, optional) | 34... |
INFURA_API_KEY | Infura project ID for RPC endpoints | 66... |
Verification Variables¶
| Variable | Description |
|---|---|
ETHERSCAN_API_KEY | Etherscan API key (used for Etherscan V2 API across all chains) |
BASESCAN_API_KEY | Basescan-specific API key (fallback) |
Token Variables¶
| Variable | Network | Description |
|---|---|---|
WRAPPED_VERDIKTA_TOKEN | Default | Wrapped VDKA token address |
WRAPPED_VERDIKTA_TOKEN_BASE_SEPOLIA | Base Sepolia | Network-specific override |
WRAPPED_VERDIKTA_TOKEN_BASE | Base mainnet | Network-specific override |
Optional Variables¶
| Variable | Description |
|---|---|
SKIP_MIGRATIONS | Set to any value to skip deployment scripts |
Deployed Contract Addresses¶
Base Sepolia (Testnet)¶
| Contract/Token | Address |
|---|---|
| LINK Token | 0xE4aB69C077896252FAFBD49EFD26B5D171A32410 |
| Verdikta Token | 0xe46F6b494F111d958CDBB52536AD78c4eEeB0149 |
| Wrapped Verdikta Token (Aggregator) | 0x2F1d1aF9d5C25A48C29f56f57c7BAFFa7cc910a3 |
| Wrapped Verdikta Token (Singleton) | 0x94e3c031fe9403c80E14DaFbCb73f191C683c2B1 |
| ReputationKeeper (Singleton) | 0xE09821277D9af702F7910a57e85EaC6D83e4d794 |
Base (Mainnet)¶
| Contract/Token | Address |
|---|---|
| LINK Token | 0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196 |
| Wrapped Verdikta Token | 0x1EA68D018a11236E07D5647175DAA8ca1C3D0280 |
Ethereum Sepolia (Testnet)¶
| Contract/Token | Address |
|---|---|
| LINK Token | 0x779877A7B0D9E8603169DdbD7836e478b4624789 |
| Verdikta Token | 0xbb7079F45367ce928789cc40d8C9D4E3A19b0a49 |
Deployment Procedures¶
All projects use hardhat-deploy unless otherwise noted. Deployments are run via npx hardhat deploy --network <network>.
1. ReputationAggregator + ReputationKeeper¶
This is the primary deployment. Located in reputationBasedAggregator/.
The deployment runs three sequential scripts:
Step 1: Deploy ReputationAggregator (deploy/01_aggregator.js)¶
Deploys the aggregator with a dummy keeper address (zero address). The real keeper is wired in step 2.
Constructor args: (linkTokenAddress, address(0))
The LINK token address is resolved by network: - Base Sepolia: 0xE4aB69C077896252FAFBD49EFD26B5D171A32410 - Base mainnet: 0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196 - Sepolia: 0x779877A7B0D9E8603169DdbD7836e478b4624789
Step 2: Deploy ReputationKeeper (deploy/02_keeper.js)¶
Deploys the keeper and wires it bidirectionally to the aggregator:
- Deploys
ReputationKeeper(wrappedVerdiktaTokenAddress) - Calls
keeper.approveContract(aggregatorAddress)— allows the aggregator to select oracles and update scores - Calls
aggregator.setReputationKeeper(keeperAddress)— points the aggregator at the keeper
The Wrapped Verdikta token address is resolved from environment variables in order of preference: 1. WRAPPED_VERDIKTA_TOKEN_BASE_SEPOLIA (for Base Sepolia) 2. WRAPPED_VERDIKTA_TOKEN_BASE (for Base mainnet) 3. WRAPPED_VERDIKTA_TOKEN (generic fallback)
Step 3: Configure (deploy/03_config.js)¶
Sets operational parameters on both contracts:
- Verifies/sets the VDKA token address in the keeper
- Calls
aggregator.setConfig(6, 4, 3, 2, 300)— K=6, M=4, N=3, P=2, timeout=300s - Calls
aggregator.setMaxOracleFee(0.05 LINK)
All-in-one Deployment¶
This runs all three scripts in order (01 → 02 → 03) via hardhat-deploy dependency resolution.
2. ReputationSingleton¶
Located in reputationBasedSingleton/. Uses an existing ReputationKeeper deployment.
Step 1: Deploy Singleton (deploy/01_singleton.js)¶
Reads keeper and linkToken addresses from deployment-addresses.json (base_sepolia section).
Constructor args: (linkTokenAddress, keeperAddress)
Step 2: Configure (deploy/02_config.js)¶
Performs several wiring and verification steps:
- Reads the keeper address from
deployment-addresses.json - Probes
keeper.isContractApproved(singletonAddress)to check if already approved - Calls
keeper.approveContract(singletonAddress)if needed - Verifies
selectOraclesconnectivity by calling it as the singleton - Cross-checks LINK token consistency between singleton and operator contracts
3. ArbiterOperator¶
Located in arbiterOperator/. This is the oracle node's operator contract.
Note: The ArbiterOperator uses a direct deploy script (scripts/deploy.js), not hardhat-deploy.
Constructor args: (linkTokenAddress)
Post-Deployment: Wire to ReputationKeeper¶
# Add the ReputationKeeper to the operator's allowlist
npx hardhat run scripts/manageReputationKeepers.js --network base_sepolia
# Set authorized senders (Chainlink node addresses)
npx hardhat run scripts/setAuthorizedSenders.js --network base_sepolia
4. SimpleContract¶
Located in simpleContract/. Pre-configured with a fixed oracle.
Edit deploy/01_simple_contract.js to set your oracle address, job ID, fee, and class before deploying.
Current hardcoded defaults for Base Sepolia: - Oracle: 0x00A08b75178de0e0d7FF13Fdd4ef925AC3572503 - Job ID: 6c751f1a36f348dc8655c11e0f804b31 (16 bytes, right-padded to bytes32) - Fee: 0.01 LINK - LINK: 0xE4aB69C077896252FAFBD49EFD26B5D171A32410 - Class: 128
5. DemoClient¶
Located in demoClient/. A test client contract for end-to-end verification.
Edit deploy/01_demo_client.js to set the aggregator address and LINK token address.
Current hardcoded defaults for Base Sepolia: - Aggregator: 0x65863e5e0B2c2968dBbD1c95BDC2e0EA598E5e02 - LINK: 0xE4aB69C077896252FAFBD49EFD26B5D171A32410
Post-Deployment Verification¶
Contract Verification on Block Explorer¶
All deploy scripts include automatic verification via Etherscan V2 API with retry logic (up to 4 attempts, 15-second delay). If automatic verification fails, verify manually:
npx hardhat verify --network base_sepolia \
--contract contracts/ReputationAggregator.sol:ReputationAggregator \
<address> <linkToken> <keeperAddress>
Smoke Test Checklist¶
-
Keeper wiring:
-
Contract approval:
-
Oracle registration: Register at least one oracle, then verify:
-
LINK funding: Transfer LINK to a test account and run a demo query:
Oracle Registration Verification¶
After deploying an ArbiterOperator and registering it with the ReputationKeeper:
cd reputationBasedAggregator
npx hardhat run scripts/register-oracle.js --network base_sepolia
npx hardhat run scripts/monitor-contracts.js --network base_sepolia
Compiler Configuration¶
| Project | Solidity Version | Optimizer | viaIR |
|---|---|---|---|
| reputationBasedAggregator | 0.8.30 | 200 runs | Yes |
| reputationBasedSingleton | 0.8.30 | 200 runs | Yes |
| arbiterOperator | 0.8.19 | 200 runs | No |
| simpleContract | 0.8.21 | 200 runs | No |
| demoClient | 0.8.19 | 200 runs | No |
Network-Specific Notes¶
Base Sepolia¶
- Recommended gas price: 300 Mwei (
gasPrice: 300_000_000in hardhat config) - Block confirmations: 2
- LINK faucet: Available via Chainlink faucet
Base Mainnet¶
- Uses EIP-1559 fee estimation (no fixed gas price)
- Block confirmations: 2
- Deployment uses
deterministicDeployment: false(ordinary CREATE, not CREATE2)
Ethereum Sepolia¶
- Gas price: 10 Gwei
- Gas limit: 18.5M
- Block confirmations: 1
Utility Scripts¶
The reputationBasedAggregator/scripts/ directory contains several operational tools:
| Script | Purpose |
|---|---|
register-oracle.js | Register an oracle with the keeper |
unregister-oracle.js | Deregister an oracle |
monitor-contracts.js | Monitor contract state and events |
oracle-poller.js | Poll oracle status |
approve-link.js | Approve LINK spending |
configure-contracts.js | Update contract configuration |
reset-reputations-cl.js | Reset all reputation scores |
single-query.js | Submit a single test query |
agg-history.js | View aggregation history |
withdraw-link-from-oracle.js | Withdraw LINK from oracle contract |
show-gas.js | Display gas usage statistics |