Jeder Gewinner kommt aus einer gewichteten Zufallsauslosung. Jedes Los, das du verdienst, wird ein Platz im Pool, 5 Lose geben dir also 5 Plätze und 5 Chancen. Wenn das Giveaway endet, zieht unser Code zufällig Plätze mit crypto.randomInt, einem kryptografisch sicheren Generator ohne Seed, den irgendwer vorhersagen oder beeinflussen könnte. Den genauen Auslosungs-Code kannst du weiter oben auf dieser Seite lesen.
Offener Algorithmus
So lost ScopliDrop Gewinner aus,
und warum du es nachprüfen kannst
Unser offengelegter Algorithmus sorgt für eine komplett faire Auslosung. Mehr Lose = bessere Chancen, aber jede teilnehmende Person hat eine echte Chance zu gewinnen. Keine Manipulation, keine Bevorzugung, keine Ausnahmen.
Unser Transparenz-Versprechen
Vertrauen entsteht durch Transparenz. Jeder Schritt unserer Auslosung ist offen einsehbar. Keine Blackbox, keine versteckten Algorithmen, keine geheimen Parameter. Was du siehst, ist genau das, was passiert.
Der Algorithmus hinter der Auslosung
Jeder Gewinner wird von diesem Code ausgelost, direkt aus unserer Codebasis. Kryptografisch sicherer Zufall, keine versteckten Funktionen, keine geheimen Parameter.
WinnerSelection.ts
1// src/lib/services/WinnerSelection.ts2import { randomInt } from 'crypto';3import { GiveawayEntry } from '@/components/dashboard/giveaways/types';45/**6 * Select winners using weighted random selection7 * @param entries Array of giveaway entries with user IDs and entry counts8 * @param winnerCount Number of winners to select9 * @param hasFraudDetection Whether the server has fraud detection enabled (premium+)10 * @param cooldownExcludedUserIds Optional array of user IDs to exclude due to winner cooldown11 * @param geoExcludedUserIds Optional array of user IDs to exclude due to geo restriction12 * (warn-mode entrants and block-mode strays that slipped past the submit gate)13 * @param referralExcludedUserIds Optional array of user IDs to exclude because they are14 * below the giveaway's Invite-to-Win referral requirement (premium feature)15 * @returns Array of selected winner user IDs16 */17export function selectWinners(18 entries: GiveawayEntry[],19 winnerCount: number,20 hasFraudDetection: boolean = true, // Default to true for backward compatibility21 cooldownExcludedUserIds: string[] = [], // Users excluded due to recent wins (cooldown)22 geoExcludedUserIds: string[] = [], // Users excluded due to geo restriction23 referralExcludedUserIds: string[] = [] // Users below the Invite-to-Win referral requirement24): string[] {25 if (!entries || entries.length === 0) {26 return [];27 }2829 // Create a Set for O(1) lookup of cooldown excluded users30 const cooldownExcludedSet = new Set(cooldownExcludedUserIds);3132 // Filter out:33 // 1. Red-flagged entries ONLY if server has fraud detection enabled (premium+)34 // 2. Users on winner cooldown (won from this server recently)35 // 3. Users whose entry country falls under the giveaway's geo restriction36 // 4. Users below the giveaway's Invite-to-Win referral requirement37 let eligibleEntries = hasFraudDetection38 ? entries.filter(entry => entry.fraud_flag !== 'red')39 : entries; // Free servers: include all entries (ignore fraud flags)4041 // Apply cooldown exclusions (silent exclusion - users can still enter but won't win)42 if (cooldownExcludedSet.size > 0) {43 const beforeCount = eligibleEntries.length;44 eligibleEntries = eligibleEntries.filter(entry => !cooldownExcludedSet.has(entry.user_id));45 const excluded = beforeCount - eligibleEntries.length;46 if (excluded > 0) {47 console.log(`[Winner Selection] Excluded ${excluded} entries due to winner cooldown`);48 }49 }5051 // Apply geo exclusions (warn mode: entered with disclosure, can't win)52 const geoExcludedSet = new Set(geoExcludedUserIds);53 if (geoExcludedSet.size > 0) {54 const beforeCount = eligibleEntries.length;55 eligibleEntries = eligibleEntries.filter(entry => !geoExcludedSet.has(entry.user_id));56 const excluded = beforeCount - eligibleEntries.length;57 if (excluded > 0) {58 console.log(`[Winner Selection] Excluded ${excluded} entries due to geo restriction`);59 }60 }6162 // Apply Invite-to-Win exclusions (entrants below the referral requirement;63 // participants were told up-front they must invite X friends to be eligible)64 const referralExcludedSet = new Set(referralExcludedUserIds);65 if (referralExcludedSet.size > 0) {66 const beforeCount = eligibleEntries.length;67 eligibleEntries = eligibleEntries.filter(entry => !referralExcludedSet.has(entry.user_id));68 const excluded = beforeCount - eligibleEntries.length;69 if (excluded > 0) {70 console.log(`[Winner Selection] Excluded ${excluded} entries below the Invite-to-Win referral requirement`);71 }72 }7374 // If no eligible entries remain (after fraud + cooldown + geo + referral filtering), return empty array75 if (eligibleEntries.length === 0) {76 console.warn('[Winner Selection] No eligible entries after filtering (fraud flags + cooldown + geo + referral-requirement exclusions)');77 return [];78 }7980 // Create weighted pool of entries based on entry count81 const entryPool: string[] = [];8283 for (const entry of eligibleEntries) {84 // Add user_id to the pool based on their entry count85 for (let i = 0; i < entry.entries_count; i++) {86 entryPool.push(entry.user_id);87 }88 }8990 // Randomly select winners without duplicates91 const winners: string[] = [];92 const winnerSet = new Set<string>();9394 // Limit winner count to available unique participants (only eligible entries)95 const uniqueParticipants = new Set(eligibleEntries.map(entry => entry.user_id));96 const availableWinnerCount = Math.min(winnerCount, uniqueParticipants.size);97 98 // If there are no entries or the pool is empty, return empty array99 if (availableWinnerCount === 0 || entryPool.length === 0) {100 return [];101 }102 103 // Select winners104 while (winners.length < availableWinnerCount && entryPool.length > 0) {105 // Select a random entry from the pool106 const randomIndex = randomInt(entryPool.length);107 const selectedUserId = entryPool[randomIndex];108109 // If this user hasn't already been selected as a winner, add them110 if (!winnerSet.has(selectedUserId)) {111 winners.push(selectedUserId);112 winnerSet.add(selectedUserId);113 }114115 // Remove via swap-and-pop (O(1)) instead of splice (O(n)).116 // Selection is uniform random so order of remaining elements doesn't matter.117 entryPool[randomIndex] = entryPool[entryPool.length - 1];118 entryPool.pop();119 }120 121 return winners;122}Die wichtigsten Schritte
Klicke auf einen Schritt, um seine Umsetzung im Code zu sehen
Zeile 2
Sicherer Zufall
Gewinner werden mit crypto.randomInt von Node ausgelost, einem kryptografisch sicheren Generator. Es gibt keinen Seed, den man vorhersagen könnte, und nichts zu manipulieren, auch nicht für uns.
Zeile 38
Betrugs- und Cooldown-Filter
Vor der Auslosung werden auf Servern mit Betrugserkennung markierte Teilnahmen entfernt, und wer im Gewinner-Cooldown ist, bleibt außen vor. Free-Server behalten jede Teilnahme.
Zeile 86
Gewichteter Pool
Hier beginnt die Fairness. Jede Person kommt einmal pro verdientem Los in den Pool, 5 Lose heißen also 5 Chancen. Proportional, nie garantiert.
Zeile 106
Die Auslosung
Ein zufälliger Index im gewichteten Pool bestimmt jeden Gewinner. Mehr Lose heißen einfach mehr Plätze, und jeder Platz hat exakt dieselbe Chance.
Zeile 110
Kein doppelter Gewinn
Ein Gewinner-Set stellt sicher, dass niemand zweimal gewinnt, und wir losen nie mehr Gewinner aus, als es teilnahmeberechtigte Personen gibt.
So funktioniert die Fairness
Sieh genau, wie unser Algorithmus jeder teilnehmenden Person eine faire Chance gibt, mit besseren Chancen für die, die mehr machen.
1
Lose sammeln
Mitglieder erledigen Aufgaben und verdienen Lose für ihre Aktionen
2
Gewichteter Pool
Jedes Los kommt je nach erledigten Aufgaben in den Auslosungs-Pool
3
Zufällige Auswahl
Kryptografisch sicherer Zufall wählt aus dem gewichteten Pool
4
Kein doppelter Gewinn
Stellt sicher, dass jede Person pro Giveaway nur einmal gewinnen kann
5
Gewinner bestätigen
Die ausgelosten Gewinner werden geprüft und verkündet
Konkretes Beispiel
Alice erledigt 3 Aufgaben, Bob 1 Aufgabe, Charlie 5 Aufgaben. Der Pool enthält insgesamt 9 Lose, mit proportionalen Gewinnchancen.
Alice
3 Lose verdient
33% Chance
Bob
1 Los verdient
11% Chance
Charlie
5 Lose verdient
56% Chance
Der Pool (9 Lose insgesamt)
Jeder Punkt steht für ein Los. Der Gewinner wird zufällig aus allen Losen gezogen.
Schluss mit manipulierten Giveaways
Ein Discord-Giveaway-Bot, der genau zeigt, wie Gewinner ausgelost werden
Das Problem
Die meisten Discord-Giveaway-Bots sind Blackboxen. Selbst wenn der Bot seriös ist und wirklich zufällig auslost, kann deine Community das nicht nachprüfen. Sie sieht den Algorithmus nicht, kann den Ablauf nicht kontrollieren und nicht belegen, dass die Gewinner nicht von Hand ausgesucht wurden.
Ohne Transparenz wirkt jedes Giveaway verdächtig. Deine Mitglieder fragen sich irgendwann, ob es überhaupt fair zugeht. Das Vertrauen stirbt, das Engagement sinkt.
Wir hatten genug davon, Communitys an verlorenem Vertrauen sterben zu sehen
Die Lösung
Nie wieder Engagement verlieren, weil jemand „manipuliertes Giveaway“ ruft. Wenn Mitglieder an der Fairness zweifeln, schick ihnen einfach den Link zu dieser Seite.
Der Giveaway-Bot ScopliDrop garantiert, dass Server-Inhaber Giveaways weder bearbeiten noch Gewinner auswählen können. Punkt.
Es gibt eine Funktion „Giveaway manuell beenden“, aber die startet nur unseren Auslosungs-Algorithmus, sonst nichts. Server-Admins KÖNNEN KEINE Gewinner auswählen, auf keinem Weg. Das ist unser Versprechen.
Fragen zur Fairness
So stellen wir sicher, dass jedes Giveaway transparent, sicher und für alle Teilnehmenden fair ist.
Mach mit bei der fairen Revolution
Bereit für wirklich faire
Giveaways, ab heute?
Tausende Discord-Communitys sind schon auf transparente, nachprüfbare Giveaways umgestiegen. Starte kostenlos und beweise Fairness vom ersten Tag an.