Verwenden Sie unser eigenständiges Verifizierungstool, um die Ergebnisse Ihrer Spiele unabhängig zu überprüfen. Geben Sie unten die Spieldetails ein, um zu bestätigen, dass die Ergebnisse fair generiert und nicht manipuliert wurden.
Spiel
import { useEffect, useState, type ChangeEvent, type FormEvent } from "react"; import "./styles.css"; import seedrandom from "seedrandom"; import CryptoJS from "crypto-js"; import { initialInput } from "./verifier-initial-input"; const riskConfigByHouseEdge = { "0.04": { "LOW": [ { "multiplier": 0, "chance": 0.2 }, { "multiplier": 1.1, "chance": 0.44 }, { "multiplier": 1.2, "chance": 0.24 }, { "multiplier": 1.4, "chance": 0.08 }, { "multiplier": 2, "chance": 0.04 } ], "MEDIUM": [ { "multiplier": 0, "chance": 0.4 }, { "multiplier": 1.2, "chance": 0.32 }, { "multiplier": 1.5, "chance": 0.16 }, { "multiplier": 2.2, "chance": 0.08 }, { "multiplier": 4, "chance": 0.04 } ], "HIGH": [ { "multiplier": 0, "chance": 0.6 }, { "multiplier": 1.5, "chance": 0.16 }, { "multiplier": 2, "chance": 0.12 }, { "multiplier": 3, "chance": 0.08 }, { "multiplier": 6, "chance": 0.04 } ], "RISKY": [ { "multiplier": 0, "chance": 0.84 }, { "multiplier": 2, "chance": 0.04 }, { "multiplier": 3, "chance": 0.04 }, { "multiplier": 4, "chance": 0.04 }, { "multiplier": 15, "chance": 0.04 } ] }, "0.08": { "LOW": [ { "multiplier": 0, "chance": 0.2 }, { "multiplier": 1, "chance": 0.44 }, { "multiplier": 1.2, "chance": 0.24 }, { "multiplier": 1.4, "chance": 0.08 }, { "multiplier": 2, "chance": 0.04 } ], "MEDIUM": [ { "multiplier": 0, "chance": 0.4 }, { "multiplier": 1.1, "chance": 0.32 }, { "multiplier": 1.5, "chance": 0.16 }, { "multiplier": 2.1, "chance": 0.08 }, { "multiplier": 4, "chance": 0.04 } ], "HIGH": [ { "multiplier": 0, "chance": 0.6 }, { "multiplier": 1.5, "chance": 0.16 }, { "multiplier": 2, "chance": 0.12 }, { "multiplier": 3, "chance": 0.08 }, { "multiplier": 5, "chance": 0.04 } ], "RISKY": [ { "multiplier": 0, "chance": 0.84 }, { "multiplier": 2, "chance": 0.04 }, { "multiplier": 3, "chance": 0.04 }, { "multiplier": 4, "chance": 0.04 }, { "multiplier": 14, "chance": 0.04 } ] } } as const; const allTicketsCount = 100; const maxSpinCount = 10; type HouseEdge = keyof typeof riskConfigByHouseEdge; type RiskLevel = keyof (typeof riskConfigByHouseEdge)[HouseEdge]; type Input = { serverSeed: string; serverSeedHash: string; clientSeed: string; nonce: string; spinCount: number | string; riskLevel: RiskLevel; houseEdge: HouseEdge; expectedMultipliers: string; }; type SpinResult = { spinNonce: number; spinSeed: string; raw: number; ticket: number; baseMultiplier: number; accumulatedMultiplier: number; }; type RiskConfigEntry = { multiplier: number; chance: number; }; const sha256 = async (value: string) => CryptoJS.SHA256(value).toString(CryptoJS.enc.Hex); const getPrivateSeed = (row: Input) => `${row.serverSeed}:${row.clientSeed}:${row.nonce}`; const roundMultiplier = (value: number) => Math.round(value * 100) / 100; const isFiniteNumber = (value: unknown): value is number => typeof value === "number" && Number.isFinite(value); const isNumberArray = (value: unknown): value is number[] => Array.isArray(value) && value.every(isFiniteNumber); const parseExpectedMultipliers = (value: string): number[] => { const trimmedValue = value.trim(); if (!trimmedValue) { return []; } const parsed: unknown = trimmedValue.startsWith("[") ? JSON.parse(trimmedValue) : trimmedValue.split(",").map((entry) => Number(entry.trim())); if (!isNumberArray(parsed)) { throw new Error("Expected multipliers must be a comma-separated list or JSON number array"); } return parsed; }; const calculateSpins = (input: Input, spinCount: number): SpinResult[] => { const privateSeed = getPrivateSeed(input); const riskConfig: readonly RiskConfigEntry[] = riskConfigByHouseEdge[input.houseEdge][input.riskLevel]; const spins: SpinResult[] = []; let previousMultiplier = 1; for (let spinNonce = 0; spinNonce < spinCount; spinNonce++) { const spinSeed = `${privateSeed}:${spinNonce}`; const raw = seedrandom(spinSeed)(); const ticket = raw * allTicketsCount; let ticketStart = 0; const selectedConfig = riskConfig.find((entry) => { const ticketEnd = ticketStart + entry.chance * allTicketsCount; const matches = ticket >= ticketStart && ticket < ticketEnd; ticketStart = ticketEnd; return matches; }); if (!selectedConfig) { throw new Error(`No Wheel interval contains ticket ${ticket}`); } const accumulatedMultiplier = selectedConfig.multiplier === 0 ? 0 : roundMultiplier(selectedConfig.multiplier * previousMultiplier); spins.push({ spinNonce, spinSeed, raw, ticket, baseMultiplier: selectedConfig.multiplier, accumulatedMultiplier, }); if (accumulatedMultiplier === 0) { break; } previousMultiplier = accumulatedMultiplier; } return spins; }; export default function App() { const [input, setInput] = useState<Input>({ ...initialInput }); const [result, setResult] = useState<React.ReactNode>(null); const [error, setError] = useState<string | null>(null); const verify = async () => { try { setError(null); if (typeof seedrandom !== "function") { throw new Error("seedrandom failed to load"); } const spinCount = Number(input.spinCount); if (!Number.isInteger(spinCount) || spinCount < 1 || spinCount > maxSpinCount) { throw new Error(`Spin count must be an integer from 1 to ${maxSpinCount}`); } const expectedMultipliers = parseExpectedMultipliers(input.expectedMultipliers); const spins = calculateSpins(input, spinCount); const calculatedMultipliers = spins.map((spin) => spin.accumulatedMultiplier); const outcomeMatches = expectedMultipliers.length > 0 && JSON.stringify(calculatedMultipliers) === JSON.stringify(expectedMultipliers); const expectedHash = await sha256(input.serverSeed); const hashBanner = (() => { if (!input.serverSeedHash) { return { message: "Server seed hash not provided", className: "verifier-result-banner", }; } if (expectedHash === input.serverSeedHash) { return { message: "Server seed hash matches", className: "verifier-result-banner verifier-result-banner-success", }; } return { message: "Server seed hash does not match", className: "verifier-result-banner verifier-result-banner-error", }; })(); const outcomeBanner = (() => { if (expectedMultipliers.length === 0) { return null; } if (outcomeMatches) { return { message: "Wheel outcome matches", className: "verifier-result-banner verifier-result-banner-success", }; } return { message: "Wheel outcome does not match", className: "verifier-result-banner verifier-result-banner-error", }; })(); setResult( <section className="verifier-result"> <div className={hashBanner.className}>{hashBanner.message}</div> {outcomeBanner && ( <div className={outcomeBanner.className}>{outcomeBanner.message}</div> )} <div className="verifier-result-grid"> <div className="verifier-result-card"> <div className="verifier-result-card-label">Calculated multipliers</div> <div className="verifier-result-card-value"> {JSON.stringify(calculatedMultipliers)} </div> </div> <div className="verifier-result-card"> <div className="verifier-result-card-label">Expected multipliers</div> <div className="verifier-result-card-value"> {expectedMultipliers.length > 0 ? JSON.stringify(expectedMultipliers) : "Not provided"} </div> </div> <div className="verifier-result-card"> <div className="verifier-result-card-label">Private seed</div> <div className="verifier-result-card-value">{getPrivateSeed(input)}</div> </div> <div className="verifier-result-card"> <div className="verifier-result-card-label">Expected server seed hash</div> <div className="verifier-result-card-value">{expectedHash}</div> </div> <div className="verifier-result-card"> <div className="verifier-result-card-label">Provided server seed hash</div> <div className="verifier-result-card-value"> {input.serverSeedHash || "Not provided"} </div> </div> </div> <div className="verifier-result-card"> <div className="verifier-result-card-label">Spins</div> <pre className="verifier-pre">{JSON.stringify(spins, null, 2)}</pre> </div> <div className="verifier-result-card"> <div className="verifier-result-card-label">Risk configuration</div> <pre className="verifier-pre"> {JSON.stringify(riskConfigByHouseEdge[input.houseEdge][input.riskLevel], null, 2)} </pre> </div> </section>, ); } catch (verifyError) { setError(verifyError instanceof Error ? verifyError.message : String(verifyError)); setResult(null); } }; useEffect(() => { void verify(); }, []); const onSubmit = (event: FormEvent<HTMLFormElement>) => { event.preventDefault(); void verify(); }; return ( <main className="verifier"> <form className="verifier-form" onSubmit={onSubmit} > <div className="verifier-form-grid"> <label className="verifier-field"> <span className="verifier-label">Server seed</span> <input className="verifier-input" name="serverSeed" value={input.serverSeed} onChange={(event: ChangeEvent<HTMLInputElement>) => { setInput((current) => ({ ...current, serverSeed: event.target.value })); }} /> </label> <label className="verifier-field"> <span className="verifier-label">Server seed hash</span> <input className="verifier-input" name="serverSeedHash" value={input.serverSeedHash} onChange={(event: ChangeEvent<HTMLInputElement>) => { setInput((current) => ({ ...current, serverSeedHash: event.target.value })); }} /> </label> <label className="verifier-field"> <span className="verifier-label">Client seed</span> <input className="verifier-input" name="clientSeed" value={input.clientSeed} onChange={(event: ChangeEvent<HTMLInputElement>) => { setInput((current) => ({ ...current, clientSeed: event.target.value })); }} /> </label> <label className="verifier-field"> <span className="verifier-label">Nonce</span> <input className="verifier-input" name="nonce" type="number" min={0} value={input.nonce} onChange={(event: ChangeEvent<HTMLInputElement>) => { setInput((current) => ({ ...current, nonce: event.target.value })); }} /> </label> <label className="verifier-field"> <span className="verifier-label">Spin count</span> <input className="verifier-input" name="spinCount" type="number" min={1} max={maxSpinCount} step={1} value={input.spinCount} onChange={(event: ChangeEvent<HTMLInputElement>) => { setInput((current) => ({ ...current, spinCount: event.target.value })); }} /> </label> <label className="verifier-field"> <span className="verifier-label">Risk level</span> <select className="verifier-input" name="riskLevel" value={input.riskLevel} onChange={(event: ChangeEvent<HTMLSelectElement>) => { setInput((current) => ({ ...current, riskLevel: event.target.value as RiskLevel, })); }} > {(["LOW", "MEDIUM", "HIGH", "RISKY"] as const).map((riskLevel) => ( <option key={riskLevel} value={riskLevel}>{riskLevel}</option> ))} </select> </label> <label className="verifier-field"> <span className="verifier-label">House edge</span> <select className="verifier-input" name="houseEdge" value={input.houseEdge} onChange={(event: ChangeEvent<HTMLSelectElement>) => { setInput((current) => ({ ...current, houseEdge: event.target.value as HouseEdge, })); }} > <option value="0.04">4%</option> <option value="0.08">8%</option> </select> </label> <label className="verifier-field"> <span className="verifier-label">Expected multipliers</span> <input className="verifier-input" name="expectedMultipliers" placeholder="1.1, 1.32, 0" value={input.expectedMultipliers} onChange={(event: ChangeEvent<HTMLInputElement>) => { setInput((current) => ({ ...current, expectedMultipliers: event.target.value, })); }} /> </label> </div> <button type="submit" className="verifier-button" > Verify </button> </form> {error && ( <div className="verifier-error">{error}</div> )} {result} </main> ); }
Acebet.de wird betrieben von Trey Mark Services Limited, einem in Zypern eingetragenen Unternehmen mit Sitz in Belapais, 4, Office 101, Strovolos, Nikosia 2057, Zypern, Registernummer HE481956. Acebet.de ist ein kostenlos spielbares Social Casino. Kein Kauf erforderlich.
Fairness-Verifizierung: Acebet.de arbeitet unter einem strengen Provably Fair Protokoll. Alle Spielergebnisse können unabhängig mit unseren Fairness-Tools und der Anpassung des Client-Seeds überprüft werden.
Sie müssen über 18 Jahre alt sein oder in Ihrer Gerichtsbarkeit die Volljährigkeit erreicht haben, um mit der Website interagieren zu können.