Oyun şeffaflığı
Nasıl çalışır:
Protokol, kamu taahhüdünü tohum açıklamasından ayırmaktadır. Bu, katılımdan sonra bir sonucun seçilmesini engeller.
1. Taahhüt
Sonuçtan önce bir karma yayınlanır. Kapalı bir dijital zarf gibi çalışır.
2. Beraberlik
Sonuç, deterministik bir işlev aracılığıyla halihazırda işlenmiş olan verilerden türetilir.
3. Açıklama
Sonuçtan sonra tohum ve gerekli parametreler incelemeye hazır hale gelir.
4. Üreme
Tarayıcı karmaları tekrarlar ve çizim yapar. Kanıt ancak her şey kayıtla eşleştiğinde geçerli olur.
Tekerlek geçirmez
Sonuç nasıl hesaplanır:
Çark, bir tohum zincirini katalog ve dönüş sırasında korunan ağırlıklarla birleştirir.
- Öğeler anahtara göre sıralanır. Her anahtar ve ağırlık, hesaplamada kullanılan kanonik kataloğa girer.
- Döndürme taahhüdü, protokol etki alanı, sunucu tohumu ve kanonik kataloğun sha-256'sıdır.
- Zincir taahhüdü başlangıçtaki hash'i, kataloğu ve boyutu bağlar; konum, tohumun yayınlanan zincire ait olduğunu kanıtlar.
- Sonuç karması, ağırlıkların toplamına göre modülo bir sayı haline gelir. Bu bilet seçilen öğeyi belirler.
Doğrulama kodu
Bunu tarayıcı konsoluna yapıştırın veya .mjs dosyası olarak kaydedin ve Node.js ile çalıştırın. Kod, karmaları ve kanıt verilerinden elde edilen çizimi yeniden hesaplar ve her parçanın eşleşip eşleşmediğini gösterir.
Kodu kanıt verileriyle doldurmak için yukarıdaki taahhüdü doğrulayın.
const proof = {
"serverSeed": "SERVER_SEED",
"commitmentHash": "COMMITMENT_HASH",
"chainCommitment": "CHAIN_COMMITMENT",
"headHash": "HEAD_HASH",
"index": 0,
"size": 1,
"items": [
{
"key": "ITEM_KEY",
"weight": 1
}
]
}
async function sha256(text) {
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text))
return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, '0')).join('')
}
async function verifyReward(proof) {
const items = [...proof.items]
.sort((left, right) => (left.key < right.key ? -1 : left.key > right.key ? 1 : 0))
.map(({ key, weight }) => ({ key, weight }))
const commitment = await sha256(
JSON.stringify(['tgrtslj:reward:commitment:v1', proof.serverSeed, items]),
)
const chain = await sha256(
JSON.stringify(['tgrtslj:reward:commitment-chain:v1', proof.headHash, items, proof.size]),
)
let link = proof.serverSeed
for (let step = 0; step <= proof.index; step += 1) link = await sha256(link)
const resultHash = await sha256(
JSON.stringify(['tgrtslj:reward:weighted-draw:v1', proof.serverSeed, items]),
)
const totalWeight = items.reduce((sum, item) => sum + item.weight, 0)
const ticket = Number(BigInt('0x' + resultHash) % BigInt(totalWeight))
let upperBound = 0
const selected = items.find((item) => ticket < (upperBound += item.weight))
return {
commitmentMatches: commitment === proof.commitmentHash,
chainMatches: chain === proof.chainCommitment,
positionMatches: proof.index < proof.size && link === proof.headHash,
resultHash,
ticket,
item: selected.key,
}
}
console.log(await verifyReward(proof))
Kazı kazan kanıtı
Sonuç nasıl hesaplanır:
Kanıt ancak ortaya çıktıktan sonra, tohum güvenli bir şekilde ifşa edilebildiğinde elde edilebilir.
- Kazı kazan kartı verildiğinde, konfigürasyon daha sonra değişse bile katalog ve ağırlıklar dondurulur.
- Taahhüt, Çark ile aynı şifreleme alanını ve ağırlıklı çekilişi kullanır.
- Tohum pozisyonu, ilk karma ve daha önce yayınlanmış zincir taahhüdüne göre kontrol edilir.
- Öğe, sonuç karması ve açıklanan tohum, kaydedilen ödülü tam olarak yeniden oluşturmalıdır.
Doğrulama kodu
Bunu tarayıcı konsoluna yapıştırın veya .mjs dosyası olarak kaydedin ve Node.js ile çalıştırın. Kod, karmaları ve kanıt verilerinden elde edilen çizimi yeniden hesaplar ve her parçanın eşleşip eşleşmediğini gösterir.
Kodu kanıt verileriyle doldurmak için yukarıdaki taahhüdü doğrulayın.
const proof = {
"serverSeed": "SERVER_SEED",
"commitmentHash": "COMMITMENT_HASH",
"chainCommitment": "CHAIN_COMMITMENT",
"headHash": "HEAD_HASH",
"index": 0,
"size": 1,
"items": [
{
"key": "ITEM_KEY",
"weight": 1
}
]
}
async function sha256(text) {
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text))
return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, '0')).join('')
}
async function verifyReward(proof) {
const items = [...proof.items]
.sort((left, right) => (left.key < right.key ? -1 : left.key > right.key ? 1 : 0))
.map(({ key, weight }) => ({ key, weight }))
const commitment = await sha256(
JSON.stringify(['tgrtslj:reward:commitment:v1', proof.serverSeed, items]),
)
const chain = await sha256(
JSON.stringify(['tgrtslj:reward:commitment-chain:v1', proof.headHash, items, proof.size]),
)
let link = proof.serverSeed
for (let step = 0; step <= proof.index; step += 1) link = await sha256(link)
const resultHash = await sha256(
JSON.stringify(['tgrtslj:reward:weighted-draw:v1', proof.serverSeed, items]),
)
const totalWeight = items.reduce((sum, item) => sum + item.weight, 0)
const ticket = Number(BigInt('0x' + resultHash) % BigInt(totalWeight))
let upperBound = 0
const selected = items.find((item) => ticket < (upperBound += item.weight))
return {
commitmentMatches: commitment === proof.commitmentHash,
chainMatches: chain === proof.chainCommitment,
positionMatches: proof.index < proof.size && link === proof.headHash,
resultHash,
ticket,
item: selected.key,
}
}
console.log(await verifyReward(proof))

