Şeffaflığı ve kanıtlanabilir adaleti sağlamak için, SHA256 çıktısının 10 milyon kez kendisine geri beslendiği bir sunucu gizli anahtarıyla başlayarak her çoklu oyunculu oyun için 10 milyon SHA256 hash'inden oluşan bir zincir oluşturduk
Platform için son hash'in SHA256'sı: eeb4d340bfaed702601b9a08faba2f8088c4810c3e3a883293accaf25053b883
Crash için son hash'in SHA256'sı: c46f0705f6ba4df891ce44accda8f89f5a6fa8b987eb7c7b445280cf6cabfbc6
Battle için son hash'in SHA256'sı: 63cb1eb64ec4eb4de02f6bad85e42365d08f37497a1b7e907bd0b9183f27e1b3
Bunu burada yayınlayarak, alternatif bir SHA256 zinciri seçme yeteneğini engelliyoruz. Şimdi oyun sunucusu, oyun sonuçlarını kanıtlanabilir şekilde adil olarak hesaplamak için bu değerleri kullanarak bu hash zincirini ters sırada oynuyor.
1. Gizli Başlangıç Hash'i: Her çoklu oyunculu oyun türünün kendi özel başlangıç hash'i vardır (yalnızca sunucu tarafından bilinir), benzersiz bir hash zincirinin kökünü oluşturur.
2. Hash Zinciri Oluşturma: Gizli başlangıç hash'inden, SHA256'yı tekrar tekrar uygulayarak 10.000.000 hash'lik bir zincir oluşturuyoruz.
func HashSeed(seed string) string {
hash := sha256.Sum256([]byte(seed))
return hex.EncodeToString(hash[:])
}
func CalculateHashChain(firstHash string) []string {
hashes := make([]string, 10_000_000)
for i := int64(0); i <= 10_000_000; i++ {
firstHash = HashSeed(firstHash)
hashes[i] = firstHash
}
return hashes
}
3. Ters Tüketim: Zincirdeki son hash'i kamuya açıklıyoruz. Her oyun turu hash'leri ters sırada tüketir: Tur 1, hash[10_000_000]'ı kullanır Tur 2, hash[9_999_999]'ı kullanır ve böyle devam eder…
4. Bu tasarım, gelecekteki hash'lerin sahtesini oluşturmayı imkansız kılarken, herkesin tüm önceki hash'leri doğrulamasına olanak tanır.
Öngörülemezlik: Gelecekteki oyun sonuçları, sunucu tarafından bile bilinemez veya etkilenemez.
Doğrulanabilirlik: Oyuncular, yalnızca kamuya açıklanan son hash'i kullanarak herhangi bir önceki turun bütünlüğünü doğrulayabilir.
Oyun İzolasyonu: Her oyun türünün kendi zinciri vardır, bu da oyunlar arası manipülasyonu önler.
Tek oyunculu oyunlarda kanıtlanabilir adaleti sağlamak için, platformumuz sonuç tohumunu oluşturmak için üç ana bileşene dayanan bir sistem kullanır:
1. İstemci Tohumu: Bu, kullanıcı tarafından kontrol edilen bir tohumdur. Bir kullanıcı kayıt olduğunda otomatik olarak oluşturulur, ancak kullanıcı bunu istediği zaman değiştirebilir. İstemci tohumunu değiştirmek, yeni bir sunucu tohumunun oluşturulmasını başlatır.
2. Sunucu Tohumu: Bu, kullanıcıya açıklanmayan dahili parametreler kullanılarak sunucu tarafından oluşturulur. Mevcut istemci tohumuna benzersiz şekilde bağlıdır. Her istemci tohumu için karşılık gelen bir sunucu tohumu vardır. Kullanıcı istemci tohumunu değiştirdiğinde, önceki sunucu tohumu doğrulama amacıyla açıklanır.
3. Nonce: Bahsin zaman damgasına (milisaniye cinsinden) dayanan benzersiz bir sayı. Tekrarlanan eylemlerin bile farklı sonuçlar üretmesini sağlar.
Bu üç değer birleştirilir ve nihai oyun tohumunu oluşturmak için HMAC-SHA256 kullanılarak hash'lenir, bu daha sonra oyunun sonucunu belirlemek için kullanılır.
func GenerateUserGameSeed(userSeed string, userServerSeed string, nonce int64) (string, error) {
data := fmt.Sprintf("%s:%s:%d", userServerSeed, userSeed, nonce)
mac := hmac.New(sha256.New, []byte(data))
gameSeed := hex.EncodeToString(mac.Sum(nil))
return gameSeed, nil
}
Sunucu, herhangi bir bahis yapılmadan önce mevcut sunucu tohumunun hash'lenmiş versiyonunu sağlar.
Kullanıcı istemci tohumunu değiştirdikten sonra, önceden kullanılan sunucu tohumu açıklanır.
Bu, kullanıcıların önceki sunucu tohumuyla oluşturulan tüm sonuçların tutarlı ve adil olduğunu doğrulamasına olanak tanır.