Commit-reveal prevents oracle front-running by requiring the oracle to commit to randomness before the raffle ends, then reveal after draw is triggered.
- Oracle generates random
secretandnonce - Computes
commitment = SHA-256(secret || nonce) - Submits commitment to contract via
commit_randomness(raffleId, commitment) - Stores secret/nonce locally for later reveal
- Oracle retrieves stored secret/nonce
- Submits to contract via
reveal_randomness(raffleId, secret, nonce) - Contract verifies:
SHA-256(secret || nonce) == stored_commitment - If valid, uses secret as randomness seed for winner selection
- Front-running prevention: Oracle cannot observe ticket purchases after committing
- Unpredictability: Secret is cryptographically random
- Verifiability: Anyone can verify the reveal matches the commitment
- Non-manipulability: Oracle cannot change commitment after submission
// Commit phase (before raffle ends)
await commitRevealWorker.processCommit({
raffleId: 1,
endTime: Date.now() + 86400000,
});
// Reveal phase (after draw triggered)
await commitRevealWorker.processReveal({
raffleId: 1,
requestId: 'req-123',
});The contract must implement:
// Commit phase
pub fn commit_randomness(env: Env, raffle_id: u32, commitment: BytesN<32>)
// Reveal phase
pub fn reveal_randomness(env: Env, raffle_id: u32, secret: BytesN<32>, nonce: BytesN<16>)Contract verification:
let computed = sha256(secret || nonce);
assert_eq!(computed, stored_commitment);✅ CommitmentService - Generate and store commitments
✅ CommitRevealWorker - Process commit and reveal phases
✅ Unit tests for commitment verification
⏳ Contract integration (waiting for contract support)
⏳ TxSubmitter methods for commit/reveal transactions
Set threshold for commit-reveal vs direct randomness:
// In worker configuration
const USE_COMMIT_REVEAL = prizeAmount >= 500; // XLM
if (USE_COMMIT_REVEAL) {
await commitRevealWorker.processCommit(...);
// Later...
await commitRevealWorker.processReveal(...);
} else {
await randomnessWorker.processRequest(...);
}npm test commitment.service.spec.ts- Commitment storage is in-memory; consider persistent storage for production
- Ensure commit happens before end_time to prevent front-running
- Monitor for failed reveals and implement retry logic