투명성과 증명 가능한 공정성을 보장하기 위해 각 멀티플레이어 게임에 대해 1,000만 개의 SHA256 해시 체인을 생성했습니다. 서버 비밀에서 시작하여 SHA256의 출력이 1,000만 번 반복적으로 자신에게 피드백되었습니다.
Platform의 최종 해시 SHA256: eeb4d340bfaed702601b9a08faba2f8088c4810c3e3a883293accaf25053b883
Crash의 최종 해시 SHA256: c46f0705f6ba4df891ce44accda8f89f5a6fa8b987eb7c7b445280cf6cabfbc6
Battle의 최종 해시 SHA256: 63cb1eb64ec4eb4de02f6bad85e42365d08f37497a1b7e907bd0b9183f27e1b3
여기에 공개함으로써 대체 SHA256 체인을 선택할 수 없게 방지합니다. 이제 게임 서버는 이 해시 체인을 역순으로 재생하며, 게임 결과를 증명 가능하게 공정하게 계산하기 위해 이 값들을 사용합니다.
1. 비밀 초기 해시: 각 멀티플레이어 게임 유형은 고유한 개인 초기 해시(서버만 알고 있음)를 가지며, 고유한 해시 체인의 루트를 형성합니다.
2. 해시 체인 생성: 초기 비밀 해시에서 SHA256을 반복적으로 적용하여 1,000만 개의 해시 체인을 생성합니다.
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. 역순 소비: 체인의 최종 해시를 공개합니다. 각 게임 라운드는 역순으로 해시를 소비합니다: 라운드 1은 hash[10_000_000]을 사용하고, 라운드 2는 hash[9_999_999]를 사용하며, 이런 식으로 계속됩니다...
4. 이 설계는 미래의 해시를 위조하는 것을 불가능하게 하지만, 누구나 이전의 모든 해시를 확인할 수 있게 합니다.
예측 불가능성: 미래의 게임 결과는 서버에서도 알거나 영향을 미칠 수 없습니다.
검증 가능성: 플레이어는 공개적으로 공개된 최종 해시만 사용하여 이전 라운드의 무결성을 확인할 수 있습니다.
게임 격리: 각 게임 유형은 자체 체인을 가지고 있어 게임 간 조작을 방지합니다.
싱글플레이어 게임에서 증명 가능한 공정성을 보장하기 위해, 당사 플랫폼은 결과 시드를 생성하기 위한 세 가지 주요 구성 요소를 기반으로 한 시스템을 사용합니다:
1. 클라이언트 시드: 사용자가 제어하는 시드입니다. 사용자 등록 시 자동으로 생성되지만 사용자는 언제든지 변경할 수 있습니다. 클라이언트 시드를 변경하면 새로운 서버 시드 생성이 시작됩니다.
2. 서버 시드: 사용자에게 공개되지 않는 내부 매개변수를 사용하여 서버에서 생성됩니다. 현재 클라이언트 시드에 고유하게 바인딩됩니다. 각 클라이언트 시드에는 해당하는 서버 시드가 있습니다. 사용자가 클라이언트 시드를 변경하면 이전 서버 시드가 검증 목적으로 공개됩니다.
3. Nonce: 베팅 타임스탬프(밀리초)에 기반한 고유 번호입니다. 반복된 조치도 다른 결과를 생성하도록 보장합니다.
이 세 값은 HMAC-SHA256을 사용하여 결합 및 해싱되어 최종 게임 시드를 생성하며, 이는 게임 결과를 결정하는 데 사용됩니다.
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
}
서버는 베팅이 이루어지기 전에 현재 서버 시드의 해시된 버전을 제공합니다.
사용자가 클라이언트 시드를 변경하면 이전에 사용한 서버 시드가 공개됩니다.
이를 통해 사용자는 이전 서버 시드로 생성된 모든 결과가 일관되고 공정했음을 확인할 수 있습니다.