Bitcoin Forum
May 08, 2024, 01:53:54 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Rocketpot Seed Event  (Read 293 times)
TheRocketman (OP)
Copper Member
Jr. Member
*
Offline Offline

Activity: 83
Merit: 5


View Profile WWW
August 23, 2019, 07:53:42 PM
Last edit: August 23, 2019, 10:26:54 PM by TheRocketman
 #1

The seed event has been designed to reflect launches of similar games on this forum.

To make it provably fair we have generated a chain of 8,000,000 SHA256 hashes where each hash is the hash of the hexadecimal representation of the previous hash. The last hash in the chain is 5de24be2ba88f21070aca0b909a23ba8977a60e047e750dc6bd637aa3b4defc8.

The formula for generating the game result:

Code:
const CryptoJS = require("crypto-js");

    function generateGameResultFromSeed(roundSeed, salt) {

      // Number of most significant bits to use
      const nBitsToUse = 52;

      // Step 1. HMAC_SHA256(message=seed, key=salt)
      const hmac = CryptoJS.HmacSHA256(roundSeed, salt);
      const roundHash = hmac.toString(CryptoJS.enc.Hex);

      // Step 2. r = 52 most significant bits
      const roundRandSource = roundHash.slice(0, nBitsToUse / 4);
      const r = parseInt(roundRandSource, 16);

      // Step 3. Calculate crash = r / 2^52, uniformly distributed in [0; 1)
      const twoPower52 = Math.pow(2, nBitsToUse);
      let crash = r / twoPower52;

      // Step 4. Calculate crash normalized in 100 - 100B range
      crash = Math.floor(97 / crash);
      crash = Math.min(crash, 100000000000);
      crash = Math.max(crash, 100);

      // Step 5. Take next 52 bits as seed for player selection in Jackpot round
      const jpPlayerRandSource = roundHash.slice(nBitsToUse / 4, 2 * nBitsToUse / 4);
      const jpPlayerRandom = parseInt(jpPlayerRandSource, 16);

      // Step 6. Take next 52 bits as seed for picking Jackpot value on the wheel
      const jpValueRandSource = roundHash.slice(2 * nBitsToUse / 4, 3 * nBitsToUse / 4);
      const jpValueRandom = parseInt(jpValueRandSource, 16);

      return {roundHash, jpPlayerRandom, jpValueRandom, crash, roundSeed};
    }

The client seed is the hash of a future bitcoin block that has not been mined at the time of this post. The block we will use is 591433. This way players can be certain that we did not deliberately pick a client seed which advantages the house.

1715133234
Hero Member
*
Offline Offline

Posts: 1715133234

View Profile Personal Message (Offline)

Ignore
1715133234
Reply with quote  #2

1715133234
Report to moderator
Bitcoin mining is now a specialized and very risky industry, just like gold mining. Amateur miners are unlikely to make much money, and may even lose money. Bitcoin is much more than just mining, though!
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1715133234
Hero Member
*
Offline Offline

Posts: 1715133234

View Profile Personal Message (Offline)

Ignore
1715133234
Reply with quote  #2

1715133234
Report to moderator
1715133234
Hero Member
*
Offline Offline

Posts: 1715133234

View Profile Personal Message (Offline)

Ignore
1715133234
Reply with quote  #2

1715133234
Report to moderator
1715133234
Hero Member
*
Offline Offline

Posts: 1715133234

View Profile Personal Message (Offline)

Ignore
1715133234
Reply with quote  #2

1715133234
Report to moderator
TheRocketman (OP)
Copper Member
Jr. Member
*
Offline Offline

Activity: 83
Merit: 5


View Profile WWW
August 23, 2019, 07:56:36 PM
 #2

Here’s an archived snapshot of the page: https://archive.is/Mwq4s
Feel free to quote this post and save the original post (and confirm that block 591433 is still not mined).

RocketBot
Newbie
*
Offline Offline

Activity: 3
Merit: 1


View Profile
August 23, 2019, 08:09:10 PM
 #3

Reserved.
DarkStar_
Legendary
*
Offline Offline

Activity: 2758
Merit: 3282


View Profile WWW
August 23, 2019, 10:18:45 PM
 #4

Archived on archive.org for you. Not a lot of point in getting people to quote the thread though since you can delete any post at your pleasure, but might as well quote it too:

The seed event has been designed to reflect launches of similar games on this forum.

To make it provably fair we have generated a chain of 8,000,000 SHA256 hashes where each hash is the hash of the hexadecimal representation of the previous hash. The last hash in the chain is5de24be2ba88f21070aca0b909a23ba8977a60e047e750dc6bd637aa3b4defc8.

The formula for generating the game result:

Code:
const CryptoJS = require("crypto-js");

    function generateGameResultFromSeed(roundSeed, salt) {

      // Number of most significant bits to use
      const nBitsToUse = 52;

      // Step 1. HMAC_SHA256(message=seed, key=salt)
      const hmac = CryptoJS.HmacSHA256(roundSeed, salt);
      const roundHash = hmac.toString(CryptoJS.enc.Hex);

      // Step 2. r = 52 most significant bits
      const roundRandSource = roundHash.slice(0, nBitsToUse / 4);
      const r = parseInt(roundRandSource, 16);

      // Step 3. Calculate crash = r / 2^52, uniformly distributed in [0; 1)
      const twoPower52 = Math.pow(2, nBitsToUse);
      let crash = r / twoPower52;

      // Step 4. Calculate crash normalized in 100 - 100B range
      crash = Math.floor(97 / crash);
      crash = Math.min(crash, 100000000000);
      crash = Math.max(crash, 100);

      // Step 5. Take next 52 bits as seed for player selection in Jackpot round
      const jpPlayerRandSource = roundHash.slice(nBitsToUse / 4, 2 * nBitsToUse / 4);
      const jpPlayerRandom = parseInt(jpPlayerRandSource, 16);

      // Step 6. Take next 52 bits as seed for picking Jackpot value on the wheel
      const jpValueRandSource = roundHash.slice(2 * nBitsToUse / 4, 3 * nBitsToUse / 4);
      const jpValueRandom = parseInt(jpValueRandSource, 16);

      return {roundHash, jpPlayerRandom, jpValueRandom, crash, roundSeed};
    }

The client seed is the hash of a future bitcoin block that has not been mined at the time of this post. The block we will use is 591433. This way players can be certain that we did not deliberately pick a client seed which advantages the house.


The hash of 591433 is 00000000000000000014ccc7303b1be1fd8c6b2cb5e961d57fbdc57f661db418

taking a break - expect delayed responses
RHavar
Legendary
*
Offline Offline

Activity: 2557
Merit: 1886



View Profile
August 23, 2019, 10:23:49 PM
 #5

I'd recommend recreating this thread not as a self-moderated thread. The whole point of doing the seed event on bitcointalk is that it's a neutral 3rd party place to host it. If it's a self-moderated thread, it kinda detracts from that a lot.


Edit: Nevermind, realized the block is already mined  Embarrassed

Check out gamblingsitefinder.com for a decent list/rankings of crypto casinos. Note: I have no affiliation or interest in it, and don't even agree with all the rankings ... but it's the only uncorrupted review site I'm aware of.
TheRocketman (OP)
Copper Member
Jr. Member
*
Offline Offline

Activity: 83
Merit: 5


View Profile WWW
August 23, 2019, 10:42:21 PM
 #6

I'd recommend recreating this thread not as a self-moderated thread. The whole point of doing the seed event on bitcointalk is that it's a neutral 3rd party place to host it. If it's a self-moderated thread, it kinda detracts from that a lot.

We intended to use the archived snapshot of the page: https://archive.is/Mwq4s as the third party place to host it.

LoyceV
Legendary
*
Offline Offline

Activity: 3304
Merit: 16618


Thick-Skinned Gang Leader and Golden Feather 2021


View Profile WWW
September 02, 2019, 07:05:44 PM
 #7

This is post #7.

I confirm the topic doesn't show any deleted posts yet (except maybe by moderators). If you move (bottom-left) the thread to a board that doesn't allow self-moderation (Archival for instance) and move it back to Gambling right after that, it will no longer be self-moderated.

Here's OP's unedited post scraped 7 seconds after posting: http://loyce.club/archive/posts/5224/52246534.html (archived).

TheRocketman (OP)
Copper Member
Jr. Member
*
Offline Offline

Activity: 83
Merit: 5


View Profile WWW
September 10, 2019, 03:26:52 PM
 #8

This is post #7.

I confirm the topic doesn't show any deleted posts yet (except maybe by moderators). If you move (bottom-left) the thread to a board that doesn't allow self-moderation (Archival for instance) and move it back to Gambling right after that, it will no longer be self-moderated.

Here's OP's unedited post scraped 7 seconds after posting: http://loyce.club/archive/posts/5224/52246534.html (archived).

Thanks a lot LoyceV for the archiving. We followed your suggestion of moving the thread to Archival and then back to Gambling in order to remove the self moderation and the self moderation is now removed!

Saint-loup
Legendary
*
Offline Offline

Activity: 2604
Merit: 2353



View Profile
May 22, 2020, 09:08:40 PM
 #9

The seed event has been designed to reflect launches of similar games on this forum.

To make it provably fair we have generated a chain of 8,000,000 SHA256 hashes where each hash is the hash of the hexadecimal representation of the previous hash. The last hash in the chain is 5de24be2ba88f21070aca0b909a23ba8977a60e047e750dc6bd637aa3b4defc8.

The formula for generating the game result:

Code:
const CryptoJS = require("crypto-js");

    function generateGameResultFromSeed(roundSeed, salt) {

      // Number of most significant bits to use
      const nBitsToUse = 52;

      // Step 1. HMAC_SHA256(message=seed, key=salt)
      const hmac = CryptoJS.HmacSHA256(roundSeed, salt);
      const roundHash = hmac.toString(CryptoJS.enc.Hex);

      // Step 2. r = 52 most significant bits
      const roundRandSource = roundHash.slice(0, nBitsToUse / 4);
      const r = parseInt(roundRandSource, 16);

      // Step 3. Calculate crash = r / 2^52, uniformly distributed in [0; 1)
      const twoPower52 = Math.pow(2, nBitsToUse);
      let crash = r / twoPower52;

      // Step 4. Calculate crash normalized in 100 - 100B range
      crash = Math.floor(97 / crash);
      crash = Math.min(crash, 100000000000);
      crash = Math.max(crash, 100);

      // Step 5. Take next 52 bits as seed for player selection in Jackpot round
      const jpPlayerRandSource = roundHash.slice(nBitsToUse / 4, 2 * nBitsToUse / 4);
      const jpPlayerRandom = parseInt(jpPlayerRandSource, 16);

      // Step 6. Take next 52 bits as seed for picking Jackpot value on the wheel
      const jpValueRandSource = roundHash.slice(2 * nBitsToUse / 4, 3 * nBitsToUse / 4);
      const jpValueRandom = parseInt(jpValueRandSource, 16);

      return {roundHash, jpPlayerRandom, jpValueRandom, crash, roundSeed};
    }

The client seed is the hash of a future bitcoin block that has not been mined at the time of this post. The block we will use is 591433. This way players can be certain that we did not deliberately pick a client seed which advantages the house.
Hello
I'm sorry but I don't understand that part

       // Step 3. Calculate crash = r / 2^52, uniformly distributed in [0; 1)
      const twoPower52 = Math.pow(2, nBitsToUse);
      let crash = r / twoPower52;


I don't understand why we need to divide this number by 2^52?
The result will always be <=1, no?

██
██
██
██
██
██
██
██
██
██
██
██
██
... LIVECASINO.io    Play Live Games with up to 20% cashback!...██
██
██
██
██
██
██
██
██
██
██
██
██
RHavar
Legendary
*
Offline Offline

Activity: 2557
Merit: 1886



View Profile
May 23, 2020, 12:25:24 AM
Last edit: May 23, 2020, 01:10:00 AM by RHavar
Merited by DarkStar_ (5)
 #10

Hello
I'm sorry but I don't understand that part

       // Step 3. Calculate crash = r / 2^52, uniformly distributed in [0; 1)
      const twoPower52 = Math.pow(2, nBitsToUse);
      let crash = r / twoPower52;


I don't understand why we need to divide this number by 2^52?
The result will always be <=1, no?


I think I'm the original author of this, as it appears to be copied from bustabit. I was just trying to convert a sha256 hash into a number between 0 and 1 (and then turn that into a multiplier). The most obvious and correct way to do this would be simply get the hash (as a number) and then divide by 2^256. But as the original bustabit was written in javascript (both the server and client), I wanted to approximate that in a simple way. Javascript's only number type was a 64 bit floating point, which means it can only represent integers accurately up to 2^53 - 1. So the cleanest number less than that is 2^52, which is the max number if you read the 13 hex characters of a hash.

So basically the logic is "read the first 13 hex characters from a hash, parse as a number, divide by 2^52" and now you have a number scaled between 0 and 1.

But it's really just an artifacts of the limitations I was working with at the time (e.g. python if i was working in python, I would've just done divided the whole thing. Or if i was working with a language with proper 64 bit numbers, would've done that, etc. )

Check out gamblingsitefinder.com for a decent list/rankings of crypto casinos. Note: I have no affiliation or interest in it, and don't even agree with all the rankings ... but it's the only uncorrupted review site I'm aware of.
Saint-loup
Legendary
*
Offline Offline

Activity: 2604
Merit: 2353



View Profile
May 29, 2020, 04:31:15 PM
 #11

Hello
I'm sorry but I don't understand that part

       // Step 3. Calculate crash = r / 2^52, uniformly distributed in [0; 1)
      const twoPower52 = Math.pow(2, nBitsToUse);
      let crash = r / twoPower52;


I don't understand why we need to divide this number by 2^52?
The result will always be <=1, no?


I think I'm the original author of this, as it appears to be copied from bustabit. I was just trying to convert a sha256 hash into a number between 0 and 1 (and then turn that into a multiplier). The most obvious and correct way to do this would be simply get the hash (as a number) and then divide by 2^256. But as the original bustabit was written in javascript (both the server and client), I wanted to approximate that in a simple way. Javascript's only number type was a 64 bit floating point, which means it can only represent integers accurately up to 2^53 - 1. So the cleanest number less than that is 2^52, which is the max number if you read the 13 hex characters of a hash.

So basically the logic is "read the first 13 hex characters from a hash, parse as a number, divide by 2^52" and now you have a number scaled between 0 and 1.

But it's really just an artifacts of the limitations I was working with at the time (e.g. python if i was working in python, I would've just done divided the whole thing. Or if i was working with a language with proper 64 bit numbers, would've done that, etc. )
Thank you very much for these very precise and clear clarifications RHavar.  Smiley

But now, I don't understand why you're dividing "97" by this number :
crash = Math.floor(97 / crash);

I'm sorry for these questions but I'm trying to understand how that works.
TYVM RHavar
  


██
██
██
██
██
██
██
██
██
██
██
██
██
... LIVECASINO.io    Play Live Games with up to 20% cashback!...██
██
██
██
██
██
██
██
██
██
██
██
██
RHavar
Legendary
*
Offline Offline

Activity: 2557
Merit: 1886



View Profile
May 29, 2020, 05:08:52 PM
Merited by LoyceV (6)
 #12

Thank you very much for these very precise and clear clarifications RHavar.  Smiley

But now, I don't understand why you're dividing "97" by this number :
crash = Math.floor(97 / crash);

I'm sorry for these questions but I'm trying to understand how that works.
TYVM RHavar

So the first thing to note is that a final outcome of 123 means a multiplier of 1.23x. So `123 / crash` is easier to reason about if you think of it more like `1.23/crash` in maths terms. And as we already discussed, `crash` is evenly distributed between 0 and 1. So if you wanted to simply turn it into a multiplier you'd do:   `100 / crash`  ... but no casino is going to do that, as they need a house edge for themselves. I know bustabit effectively uses `99 / crash` to make a house edge of 1%, but rocketpot is using `97 / crash` which is going to result in a significantly higher edge (of which some will be used to fund the bonuses/jackpots/other benefit thats bustabit might not have).

Check out gamblingsitefinder.com for a decent list/rankings of crypto casinos. Note: I have no affiliation or interest in it, and don't even agree with all the rankings ... but it's the only uncorrupted review site I'm aware of.
Saint-loup
Legendary
*
Offline Offline

Activity: 2604
Merit: 2353



View Profile
May 29, 2020, 05:33:49 PM
Last edit: May 29, 2020, 06:02:54 PM by Saint-loup
 #13

Thank you very much for these very precise and clear clarifications RHavar.  Smiley

But now, I don't understand why you're dividing "97" by this number :
crash = Math.floor(97 / crash);

I'm sorry for these questions but I'm trying to understand how that works.
TYVM RHavar

So the first thing to note is that a final outcome of 123 means a multiplier of 1.23x. So `123 / crash` is easier to reason about if you think of it more like `1.23/crash` in maths terms. And as we already discussed, `crash` is evenly distributed between 0 and 1. So if you wanted to simply turn it into a multiplier you'd do:   `100 / crash`  ... but no casino is going to do that, as they need a house edge for themselves. I know bustabit effectively uses `99 / crash` to make a house edge of 1%, but rocketpot is using `97 / crash` which is going to result in a significantly higher edge (of which some will be used to fund the bonuses/jackpots/other benefit thats bustabit might not have).
hehehe TYVM for those very useful explanations  Smiley
You should have added the part on the house edge in the comments of your code IMHO, in order to allow people to easily compare the house edge between the different crash games "clones"   Wink

██
██
██
██
██
██
██
██
██
██
██
██
██
... LIVECASINO.io    Play Live Games with up to 20% cashback!...██
██
██
██
██
██
██
██
██
██
██
██
██
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!