Cheddy Golf

Giveaway draw details and verification inputs for independent reproduction.

Published inputs

Entries count
3833
Total weight
3833
Entries hash (SHA-256)
5967f6d97bf2e551013e957d5d074f79e8535e58d97773a4ed5681d558b3b5b3
Beacon source
https://drand.cloudflare.com/public/latest
Beacon round
5420143
Beacon value
5d139799051bb230d2ed17cc2edbcd70f71264c9b7e7a878d364cbd4573d48e3
Seed
19c0f43e013c71a81cecd7ba11dbd621ac50a571c5efac12f268f94446023b4e
Drawn at (UTC)
2025-09-16T15:08:36.530Z
Winner entry id(s)
71b82c36-093e-4db3-bfef-55a56cae596e

Verification algorithm

Deterministic weighted selection using HMAC-SHA256 seeded randomness from SHA256(entries_hash + '|' + beacon_value). Each entry has a weight based on their total giveaway entries earned. Selection uses cumulative weight distribution to ensure fair proportional chances.

Verify this draw (Node.js)

Copy and run with Node 18+. Download the entries array separately to avoid cluttering this view.

Download as entries.json and place in same folder as verification script
// Node 18+
const crypto = require('crypto');

function sha256Hex(input) {
  return crypto.createHash('sha256').update(input).digest('hex');
}

function deterministicWeightedSelection(weightedEntries, seedHex, winnersCount) {
  const winningEntryIds = [];
  const usedEntries = new Set();
  const seedBytes = Buffer.from(seedHex, 'hex');
  
  for (let i = 0; i < winnersCount && usedEntries.size < weightedEntries.length; i++) {
    // Create a new seed for each selection to avoid patterns
    const selectionSeed = sha256Hex(seedBytes.toString('hex') + i.toString());
    const selectionSeedBytes = Buffer.from(selectionSeed, 'hex');
    
    // Generate deterministic random number (0-1) from seed
    const randomBytes = selectionSeedBytes.slice(0, 8);
    const randomValue = randomBytes.readBigUInt64BE(0);
    const maxBigInt = BigInt('0xFFFFFFFFFFFFFFFF');
    const normalizedRandom = Number(randomValue) / Number(maxBigInt);
    
    // Calculate cumulative weights for available entries
    const availableEntries = weightedEntries.filter(e => !usedEntries.has(e.uuid));
    const availableTotalWeight = availableEntries.reduce((sum, e) => sum + e.weight, 0);
    
    let targetWeight = normalizedRandom * availableTotalWeight;
    let cumulativeWeight = 0;
    
    for (const entry of availableEntries) {
      cumulativeWeight += entry.weight;
      if (targetWeight <= cumulativeWeight) {
        winningEntryIds.push(entry.uuid);
        usedEntries.add(entry.uuid);
        break;
      }
    }
  }
  
  return winningEntryIds;
}

// Load entries from downloaded file
const fs = require('fs');
const entries = JSON.parse(fs.readFileSync('entries.json', 'utf8'));

// Published inputs
const publishedEntriesHash = "5967f6d97bf2e551013e957d5d074f79e8535e58d97773a4ed5681d558b3b5b3";
const beaconValue = "5d139799051bb230d2ed17cc2edbcd70f71264c9b7e7a878d364cbd4573d48e3";
const publishedWinners = ["71b82c36-093e-4db3-bfef-55a56cae596e"];

// 1) Verify entries hash
const entriesHash = sha256Hex(JSON.stringify(entries));
if (entriesHash !== publishedEntriesHash) {
  console.error('Entries hash mismatch:', { entriesHash, publishedEntriesHash });
  process.exit(1);
}

// 2) Derive seed
const seed = sha256Hex(publishedEntriesHash + '|' + beaconValue);

// 3) Perform weighted selection and compare winners
const winners = deterministicWeightedSelection(entries, seed, publishedWinners.length);
console.log({ winners });
console.log('Matches published:', JSON.stringify(winners) === JSON.stringify(publishedWinners));

Note: We publish opaque entry IDs only. No user handles or PII are exposed.

Back to giveaways