Welcome to the first provably fair seeding event. One of the most requested features of
Money Pot has been to create a provably distribution of game crashes, to replace our provably predetermined multipliers.
The
original scheme of turning a multiplayer game in which peers do not trust each other was first proposed by Dooglus, refined by Eric and solidified into code by Steve.
In order to ensure fairness, we need to select a client seed in a verifiable way, after we have publicised all details and cannot control the outcome of the client seed picking. This is where the seeding event comes in, we need you to witness the process to ensure nothing has changed. A good way to do this might be save the post, quote it somewhere, save a copy in some archiving services. If anyone wants me to email them a copy, PM me your email address.
Our plan is to use hash of the
bitcoin block 339300 as the client seed. If anyone finds any flaws in the code or methodology, we will push the block back to accommodate.
The technical details are as follows:
The method to create the hash chain is simply sha256:
function genGameHash(serverSeed) {
return crypto.createHash('sha256').update(serverSeed).digest('hex');
}
The method to convert a game hash to a money pot multiplier is a bit more complex:
function crashPointFromHash(serverSeed, clientSeed) {
function divisible(hash, mod) {
// We will read in 4 hex at a time, but the first chunk might be a bit smaller
// So ABCDEFGHIJ should be chunked like AB CDEF GHIJ
var val = 0;
var o = hash.length % 4;
for (var i = o > 0 ? o - 4 : 0; i < hash.length; i += 4) {
val = ((val << 16) + parseInt(hash.substring(i, i+4), 16)) % mod;
}
return val === 0;
}
var hash = crypto.createHmac('sha256', serverSeed).update(clientSeed).digest('hex');
/* In 1 of 101 games the game crashes instantly. */
if (divisible(hash, 101))
return 0;
/* Use the most significant 52-bit from the hash
to calculate the crash point */
var h = parseInt(hash.slice(0,52/4),16);
var e = Math.pow(2,52);
return Math.floor((100 * e - h) / (e - h));
}
The chain could be generated with code such as:
var serverSecret = 'If you knew this, you could steal all my money';
var clientSeed = '0000examplehash';
var gamesToGenerate = 1e7;
var serverSeed = serverSecret;
for (var game = gamesToGenerate; game > 0; --game) {
serverSeed = genGameHash(serverSeed);
console.log('Game ' + game + ' has a crash point of ' + (crashPointFromHash(serverSeed, clientSeed) / 100).toFixed(2) +'x', '\t\tHash: ' + serverSeed);
}
var terminatingHash = genGameHash(serverSeed);
console.log('The terminating hash is: ', terminatingHash);
Using our chosen starting serverSeed, the hash terminating the chain is
c1cfa8e28fc38999eaa888487e443bad50a65e0b710f649affa6718cfbfada4d. That is to say, the first game's hash played under the new provably fair scheme, when hashed will be c1cfa8e28fc38999eaa888487e443bad50a65e0b710f649affa6718cfbfada4d.
The server secret is a bitcoin private key, which corresponds to the address:
1J6qabbRQmxiii4j8mmAZ3XTvURZ8yzwfy, where a 10 bitcoin bounty awaits anyone who discovers the leaked server secret.
got it.
quoted to prevent editing.