Blockchain-IO¶
Übersicht¶
Die BO-Engine interagiert mit der Blockchain über zwei Schichten:
┌──────────────────────────────────────────────┐
│ CLI / Workers │
│ (settle.ts, recoverBuyIntents.ts, etc.) │
├──────────────────────────────────────────────┤
│ ChainReader (Read-Only) │
│ - getPotAcc(), getRolloverAcc(), etc. │
├──────────────────────────────────────────────┤
│ ethers.js 6.x │
│ - JsonRpcProvider │
│ - Wallet (Operator) │
│ - Contract (ABIs) │
├──────────────────────────────────────────────┤
│ Arbitrum One RPC │
│ (Primary + Fallback) │
└──────────────────────────────────────────────┘
ChainReader¶
Datei:
io/ChainReader.ts(66 Zeilen) Typ: Read-Only-Blockchain-Zugriff
Methoden¶
class ChainReader {
// Regular Pot für alle 5 Pools
async getPotAcc(): Promise<bigint[]>
// Rollover-Akkumulatoren für alle 5 Pools
async getRolloverAcc(): Promise<bigint[]>
// Jackpot-Reserve für alle 5 Pools
async getJackpotReserveAcc(): Promise<bigint[]>
// Operator-Fee für einen bestimmten Tag
async getFeeAcc(dayId: number): Promise<bigint>
// No-Hit-Streak (Tage ohne Jackpot) pro Pool
async getJackpotNoHitStreak(): Promise<number[]>
}
Verwendete Contracts¶
| Contract | Methoden | Verwendung |
|---|---|---|
| GameTreasury | potAcc(), rolloverAcc(), jackpotReserveAcc(), feeAcc() |
Pot-State für Settlement |
| SettlementV4/V5 | jackpotStates(), daySettled(), lastSettledDay() |
Jackpot-State, Settlement-Status |
Initialisierung¶
// ChainReader.ts
const provider = new JsonRpcProvider(RPC_URL);
const treasury = new Contract(GAME_TREASURY, GameTreasuryABI, provider);
const settlement = new Contract(SETTLEMENTV4, SettlementV4ABI, provider);
Contract-Interaktionen¶
Write-Operationen (mit Operator-Wallet)¶
| Operation | Contract | Methode | Worker |
|---|---|---|---|
| Settlement Commit | SettlementV4/V5 | commitMerkleSettlement() |
commit_from_db.ts |
| VRF-Seed-Request | VRFReceiverV3 | requestVrfSeed() |
refreshSeeds.ts |
| Drand-Seed-Setzen | GameManagerV3 | setDrandSeed() |
refreshSeeds.ts |
| Auto-Bonus-Vergabe | BonusManager | grantAutoBonus() |
processBonusGrant.ts |
Read-Operationen (ohne Wallet)¶
| Operation | Contract | Methode | Worker |
|---|---|---|---|
| Pot-Sizes | GameTreasury | potAcc(), rolloverAcc() |
updatePotSizes.ts |
| Jackpot-State | SettlementV4/V5 | jackpotStates() |
ChainReader, updatePotSizes |
| Day-Settled | SettlementV4/V5 | daySettled() |
settle.ts |
| VRF-Status | VRFReceiverV3 | vrfSeed(), fulfilledTimestamp() |
refreshSeeds.ts |
| Ticket-Counter | GameManagerV3 | vrfTicketCounter() |
refreshSeeds.ts |
| Charity-Balance | USDT Token | balanceOf(CharityVault) |
updatePotSizes.ts |
| Relayer-Balance | - | getBalance() |
Watchdog |
Event-Listening¶
| Event | Contract | Verwendung |
|---|---|---|
PrizeVaultPayout |
PrizeVault | backfill_claim_events.ts |
AffiliateVaultPayout |
AffiliateVault | backfill_claim_events.ts |
TicketCreated |
GameManager | finalizeBuyIntent_v2.ts |
Contract-ABIs¶
Verzeichnis:
abi/undtypes/solidity.ts
solidity.ts¶
// types/solidity.ts (100 Zeilen)
// Enthält inline ABI-Definitionen für:
const GameTreasuryABI = [
"function potAcc(uint256 poolId) view returns (uint256)",
"function rolloverAcc(uint256 poolId) view returns (uint256)",
"function jackpotReserveAcc(uint256 poolId) view returns (uint256)",
"function feeAcc(uint256 dayId) view returns (uint256)"
];
const SettlementV4ABI = [
"function commitMerkleSettlement(...)",
"function jackpotStates(uint256 poolId) view returns (tuple(...))",
"function daySettled(uint256 dayId) view returns (bool)",
"function lastSettledDay() view returns (uint256)"
];
const GameManagerABI = [
"function vrfSeed() view returns (bytes32)",
"function drandSeed() view returns (bytes32)",
"function vrfTicketCounter() view returns (uint256)",
"function setDrandSeed(bytes32 seed)"
];
const VRFReceiverABI = [
"function requestVrfSeed()",
"function lastVrfSeed() view returns (bytes32)",
"function fulfilledTimestamp() view returns (uint256)"
];
SettlementV4.json¶
Vollständige ABI (~15 KB) für das Settlement-Contract.
Artefakt-Writer¶
Datei:
io/artifactWriter.ts(118 Zeilen)
Funktionen¶
class ArtifactWriter {
// JSON schreiben mit stabiler Key-Sortierung
async writeJson(filename: string, data: object): Promise<string>
// Text-Datei schreiben
async writeText(filename: string, content: string): Promise<string>
// Checksums.json generieren (SHA256 aller Dateien)
async finalize(): Promise<void>
}
Features¶
- Deterministische Serialisierung: Keys alphabetisch sortiert
- BigInt-Konvertierung: BigInt → String (für JSON-Kompatibilität)
- SHA256-Checksums: Jede Datei erhält einen Hash in
checksums.json - Verzeichnisstruktur:
artifacts/dayId=X/
Artefakt-Dateien pro Tag¶
| Datei | Inhalt | Quelle |
|---|---|---|
inputs.json |
Gewinner nach Pool/Klasse | export_inputsDB.ts |
affiliates.json |
Affiliate-Daten | export_affiliatesDB.ts |
settlement_result.json |
Berechnungsergebnis + Audit | run.ts |
winners_merkle.json |
Merkle-Root + Leaves + Proofs | run.ts |
affiliate_merkle.json |
Affiliate-Merkle-Daten | run.ts |
commit_bundle.json |
On-Chain-Commit-Parameter | run.ts |
checksums.json |
SHA256 aller Dateien | finalize() |
RPC-Konfiguration¶
Primary + Fallback¶
// Environment-Variablen
RPC_URL // Primary Arbitrum RPC
FALLBACK_RPC_URL // Backup (optional, default: RPC_URL)
Dual-RPC-Nutzung¶
recoverBuyIntents.ts:
├── Primary RPC: Erste Receipt-Abfrage
└── Fallback RPC: Wenn Primary kein Ergebnis liefert
Watchdog:
└── Primary RPC: Health-Check (S2)
Settlement:
├── Finalized Block: waitUntilDayIsReady()
└── ChainReader: State-Abfragen
Error-Handling¶
// Typisches Pattern für RPC-Aufrufe
try {
const result = await provider.getTransactionReceipt(txHash);
return result;
} catch (e) {
console.error("RPC error:", e.message);
// Fallback oder Retry je nach Kontext
}
USDT-Beträge¶
Alle Beträge werden als Integer mit 6 Dezimalstellen gespeichert (USDT-Standard):