사용자 지정 게임 - 공정성 입증
커스텀 게임에서 사용되는 방법
YEET Original의 모든 베팅은 라운드 시드에서 시작됩니다. 라운드 시드는 클라이언트 시드와 베팅의 nonce를 HMAC-SHA256으로 해싱한 값이며, YEET이 선택한 서버 시드가 키로 사용됩니다. 게임은 해당 베팅에 필요한 모든 무작위 값을 이 라운드 시드에서 추출합니다. 서버 시드는 플레이하기 전에 해싱된 상태로 표시되며, 시드 페어를 교체할 때 공개되므로 과거 베팅의 라운드 시드를 다시 계산하여 결과가 조작되지 않았는지 확인할 수 있습니다.
다른 검증 결과와 일치하지 않을 수 있음
다른 카지노용으로 제작된 검증 사이트는 무작위 숫자 생성 방식이 다를 수 있으므로, 해당 사이트에서 YEET 베팅을 확인하면 결과가 다르게 나올 수 있습니다. YEET 베팅은 게임의 공정성 창에 있는 검증 탭이나 이 페이지의 코드를 사용하여 확인하세요.
전환
변환은 라운드 시드의 엔트로피를 게임 결과로 바꿉니다. 모든 Original 게임의 기본 구성 요소는 동일합니다. unbiasedUint가 동일한 확률의 n개 위치 중 하나를 선택하면, 게임은 해당 위치가 당첨인지 확인합니다. n개 중 s개의 당첨 위치를 가진 단계의 확률은 s / n입니다.
이 페이지는 모든 게임의 변환을 나열하지는 않습니다. 아래 예시는 한 게임의 패턴을 보여줍니다.
예시: 램 찹(Lamb Chop)
램 찹은 16번의 홉을 가지며, 각 홉은 동일한 라운드 시드에서 한 번씩 추첨됩니다. 홉 h에서 레인에는 totalStart − h개의 위치가 있고, 그중 safeStart − h개는 안전합니다. 안전한 위치의 개수보다 낮은 숫자가 나오면 생존합니다. 생존하지 못한 첫 번째 롤에서 라운드가 종료되며, 배당률은 통과한 홉의 개수에 따라 페이테이블에서 확인됩니다.
const LAMB_CHOP_TOTAL_HOPS = 16;
const LAMB_CHOP_LANES = {
easy: [19, 21],
medium: [19, 23],
hard: [19, 25],
very_hard: [19, 27],
death_wish: [20, 32],
};
const LAMB_CHOP_PAYTABLE = {
easy: [
1.0721, 1.1912, 1.3313, 1.4977, 1.6975, 1.94, 2.2384, 2.6115,
3.0863, 3.7036, 4.5266, 5.6583, 7.275, 9.7, 13.58, 20.37,
],
medium: [
1.1742, 1.4351, 1.7728, 2.216, 2.8069, 3.6089, 4.7194, 6.2925,
8.5807, 12.013, 17.3522, 26.0283, 40.9016, 68.1694, 122.705, 245.41,
],
hard: [
1.2763, 1.7017, 2.3023, 3.1657, 4.432, 6.3315, 9.2537, 13.8806,
21.4519, 34.323, 57.2051, 100.1089, 185.9166, 371.8333, 818.0333, 2045.0833,
],
very_hard: [
1.3784, 1.991, 2.928, 4.392, 6.7344, 10.5826, 17.0951, 28.4918,
49.2132, 88.5838, 167.325, 334.65, 717.1071, 1673.25, 4350.45, 13051.35,
],
death_wish: [
1.552, 2.5322, 4.2203, 7.1994, 12.5989, 22.6781, 42.1166, 80.9934,
161.9869, 338.7, 745.1401, 1738.6604, 4346.651, 11798.0529, 35394.1588, 120340.14,
],
};
async function verifyLambChopBet(serverSeed, clientSeed, nonce, volatility) {
const seed = await deriveGameSeed(serverSeed, clientSeed, nonce);
const result = await verifyLambChopFromSeed(seed, volatility);
return { serverSeed, clientSeed, nonce, ...result };
}
async function verifyLambChopFromSeed(seed, volatility) {
const lane = LAMB_CHOP_LANES[volatility];
if (!lane) throw new Error(`No lamb-chop lane geometry for risk profile '${volatility}'.`);
const [safeStart, totalStart] = lane;
const entropy = new GameEntropy(hexToBytes(seed));
const hops = [];
let bustIndex = LAMB_CHOP_TOTAL_HOPS;
for (let hop = 0; hop < LAMB_CHOP_TOTAL_HOPS; hop++) {
const safePositions = safeStart - hop;
const totalPositions = totalStart - hop;
const roll = await unbiasedUint(entropy, totalPositions);
const survived = roll < safePositions;
hops.push({
hop,
safePositions,
totalPositions,
chance: safePositions / totalPositions,
roll,
survived,
});
if (!survived) {
bustIndex = hop;
break;
}
}
return {
seed,
entropyCursor: entropy.cursor,
volatility,
hops,
bustIndex,
clearedAllHops: bustIndex >= LAMB_CHOP_TOTAL_HOPS,
maxReachableMultiplier: lambChopMultiplierFor(volatility, bustIndex),
paytable: LAMB_CHOP_PAYTABLE[volatility],
};
}
function lambChopMultiplierFor(volatility, hopCount) {
if (hopCount < 1) return 0;
const row = LAMB_CHOP_PAYTABLE[volatility];
if (!row) throw new Error(`No lamb-chop paytable for risk profile '${volatility}'.`);
const multiplier = row[hopCount - 1];
if (multiplier === undefined) {
throw new Error(`No lamb-chop paytable row for ${volatility} at ${hopCount} hop(s).`);
}
return multiplier;
}
// Use the revealed server seed (64 hex characters) and the client seed and nonce shown on the bet.
console.log(await verifyLambChopBet(
'REVEALED_SERVER_SEED',
'yeetdemo-7f3a91',
'1842',
'easy'
));