Pages:
Author

Topic: Dice64 - Off Blockchain. Provably fair. Instantly verifiable. 0.9% Edge (Read 2898 times)

jr. member
Activity: 34
Merit: 1
Updated python verification code. Increased maximum bets again.

https://gist.github.com/Dice64/6151316
Code:
import hashlib
import requests
 
# Doesn't currently do signature checking, we'll implement that in soon.
URL = "https://dice64.com"
 
 
def dsha256(input):
    return hashlib.sha256(hashlib.sha256(input.decode('hex')).digest()).hexdigest()
 
 
def verify_bet(id):
    r = requests.get(URL + '/api/bets/'+str(id))
 
    if r.status_code != 200:
        print "Couldn't find bet"
        exit()
 
    secret = r.json()['secret']
    secret_hash = r.json()['secret_hash']
    nonce = r.json()['nonce']
    combined_hash = r.json()['combined_hash']
    result = r.json()['result']
    # Calculated results
    combined = int(secret, base=16) + nonce
    combined_hex = hex(combined)[2:].strip("L")
 
    # Add preceeding zeros to make it 64 bytes in length
    while len(combined_hex) < 64:
        combined_hex = "0"+combined_hex
 
    # Print output
    print "\nSecret Hash - dsha256(secret)"
    print "Calculated:", dsha256(secret)
    print "Server val:", secret_hash
 
    print "\nCombined Hash - dsha256(secret + nonce)"
    print "Calculated:", dsha256(combined_hex)
    print "Server val:", combined_hash
 
    print "\nResult - dsha256(secret + nonce) mod 64"
    print "Calculated:", long(combined_hash, base=16) % 64
    print "Server val:", result
 
 
if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('id', help='id of bet to check', type=int)
    args = parser.parse_args()
 
    verify_bet(args.id)
newbie
Activity: 25
Merit: 0
Checked it out, seems like a fun site.
jr. member
Activity: 34
Merit: 1
Site is back up, maximum bets have been increased and house edge has now been set to 0.9% for all bets.
jr. member
Activity: 34
Merit: 1
Respectable. 

Not as respectable as you, Most Respected User 2013.
sr. member
Activity: 744
Merit: 250
Vave.com - Crypto Casino
jr. member
Activity: 34
Merit: 1
Just to describe in greater detail how we prove our bets are truely verifiable, see the receipt JSON printed below.

Excess bets have been removed to improve readability and the JSON keys have been ordered in term of relevence.

After creating the account, before the player is allowed to place a bet, they must submit a signed patch statement to the service, to say they accept the following fields on the account, this must be signed with the Bitcoin address generated in the players browser;

   * userid
   * sign_address
   * deposit_address
   * return_address

This forms as a http post string, which is signed as printed below.

"PATCH /api/account\n\nuserid=1000&return_address=1FEi17iu84DmigLM9zeBfNVWzFyZYk3FGb&sign_address=1DQ6MQx5RNSk3T8evGygp95zT4jmBxXP3E&deposit_address=1KU8GojtQTkPvqWGbj9UHXrgx49h1mNXvP"

The service will then also sign this request if it is considered valid, so the player also has proof that the deposit_address belongs to Dice64, should there be and reason for a dispute.

Then for every bet you sign a request containing the following fields;
   
   * below
   * amount
   * nonce
   * secret_hash
   * multiplier

This will be a string similar to the following

"POST /api/account/bet\n\nbelow=32&amount=39000&nonce=2690345304&secret_hash=7f4ad5fb7eed63d2611b43319ec208e14395dcb71d02af678cd55c07a860a4ed&multiplier=1.980"

The service will check to ensure your signature is valid, before signing the request with the service address (1Dice64ckqzrBwEum3rDW1cKPodpvSKuEX) and returning the response.

This method ensures that we cannot at any point after the bet has been placed change any of the variables in the bet to alter the outcome. Both the player and the service have a copy of the deposit address and full list of bet requests signed by each other, as proof of anything that could have affected the players balance.


We have accountability toward every satoshi that you deposit, there is no possibility that your funds can just dissappear or be altered without us having a signed request by the player to place a bet with certain parameters which we cannot alter.

Please forward me any questions you may have.

See example of a receipt below:

Code:
{
"bet_list": [
{
"secret": "a8758b97ff72f0fcd7744ef8c9458b336f04e85d3b098388e95855a621beb918",
"secret_hash": "7f4ad5fb7eed63d2611b43319ec208e14395dcb71d02af678cd55c07a860a4ed",
"nonce": 2690345304,
"amount_placed": 39000,
"house_edge": "0.0100",
"multiplier": "1.980",

"combined_hash": "39c2176e9757844980ac26bacd90d2f5e0089b7996dfad5dc06fd91f0092820a",

"timestamp": 1375630684,
"below": 32,
"result": 10,
"won": true,

"bet_statement": "POST /api/account/bet\n\nbelow=32&amount=39000&nonce=2690345304&secret_hash=7f4ad5fb7eed63d2611b43319ec208e14395dcb71d02af678cd55c07a860a4ed&multiplier=1.980",
"bet_statement_player_sig": "HGx93DlUYwF85a2bcZWh++HuyZ+s4u70Z6lhXa3v00LpJwlh96/9fev98CcSj12dgDg57qm9sg3R/wFCeyN8Lvc=",
"bet_statement_service_sig": "HFqa7wUksX/NbEuq2AGmgRVK8TDxU5uBNynIC54Eyjwb9V26q7CW/8rbpRG1IYdZ6I0zNhZnlv9LAqD3vg8ySs4=",

"amount_won": 77220,
"profit": 38220,
"id": 1004,
"owner_id": 1000
}, ...
],

"nickname": "User 1000",
"active": false,
"expire_time": 1375630693,
"balance": 3921220,

"sign_address": "1DQ6MQx5RNSk3T8evGygp95zT4jmBxXP3E",
"deposit_address": "1KU8GojtQTkPvqWGbj9UHXrgx49h1mNXvP",
"return_address": "1FEi17iu84DmigLM9zeBfNVWzFyZYk3FGb",

"amount_placed": 156000,
"amount_won": 77220,

"profit": -78780,
"bets_placed": 4,
"bets_won": 1,

"patch_statement": "PATCH /api/account\n\nuserid=1000&return_address=1FEi17iu84DmigLM9zeBfNVWzFyZYk3FGb&sign_address=1DQ6MQx5RNSk3T8evGygp95zT4jmBxXP3E&deposit_address=1KU8GojtQTkPvqWGbj9UHXrgx49h1mNXvP",
"patch_statement_player_sig": "Gy/fpaYGDEaqaVxyUKc9y8X3I8x3cPBq9GOuGWe5c54Lhcp2pt/aHuatV38qo/48GslN/m3g9X1F2a5PYuteygc=",
"patch_statement_service_sig": "HASW/37Ez7qP6NuJqlWy8CVC2ExXr7UETCtnZg7J4zWLUtwSPdCLZJL+JIipfTJV1/KwEv5dXE/+8L0/R2xxpDw=",

"userid": 1000,
"msg": "Withdrawl Successful",
"withdrawal_txid": "e5185edad6bd33cad9086b189aaef71302eedf4a2d3114923071fac1c4bb45a2",
"withdrawal_hex": "0100000002283ea6a0994613f4c82e594790804d21fb9593d8175efef9fd3679e1e557f496000000006b483045022048c740665a821e0aabc95235dc173acbfa61e4be01c14ed5b20aa8a5c21ed3e5022100de086871fb9014e8d711df5cec3bf175a1744d2c3966f6196ff948c95ae2631b012103a7274aef7524908843c98cdff8208d25d2df3e22f6d5bb8c403b5f88c9ef6ea5ffffffffea2b965090e58496ab83ed17fe61f16b9db9c3af562b9e50c1d5fb2a80eac697000000006a47304402200b782a7a4249f52c9054c7f53c518bd5da702a1cbc9d66f4e8ddaa4ce2c872bc022041ce50f2584f3290161a41637db9be6f0ce046de3402fb216bd8713b779d00e0012103a7274aef7524908843c98cdff8208d25d2df3e22f6d5bb8c403b5f88c9ef6ea5ffffffff02bc330100000000001976a914847c7c6702c3e36f1823baf86231cfcb749f8a8d88ac34ae3b00000000001976a9149c29652d2f312210c0579faa868dc0c91202f37188ac00000000",

"deposit_list": [
{
"n": 0,
"value": 2000000,
"txid": "96f457e5e17936fdf9fe5e17d89395fb214d809047592ec8f4134699a0a63e28"
},
{
"n": 0,
"value": 2000000,
"txid": "97c6ea802afbd5c1509e2b56afc3b99d6bf161fe17ed83ab9684e59050962bea"
}
]
}
jr. member
Activity: 34
Merit: 1
So we're back up, but with a new database. All remaining accounts showed a successful payout. If anyone didn't get their money back let me know, I have signed receipts to showing the total bets and all incoming and outgoing transactions/addresses.

Using 32-bit integers as a nonce, as that is the largest amount that can be supported natively in JavaScript.

I'll be doing a write up soon, showing how the receipts can provide proof of fairness and publishing some python which can connect to the api and verify the result locally.

Thanks



hero member
Activity: 672
Merit: 500
I can't bet anymore, I keep getting internal server errors.

I've taken it offline while I update the database. I'll automatically release your current balance back to your return address in a few minutes.

that's strange, it's been more then a few minutes and it's not back yet.
EDIT: It's back.
jr. member
Activity: 34
Merit: 1
I can't bet anymore, I keep getting internal server errors.

I've taken it offline while I update the database. I'll automatically release your current balance back to your return address in a few minutes.
full member
Activity: 196
Merit: 100
I can't bet anymore, I keep getting internal server errors.

The only time I had that was when I forgot to enter a client seed/nonce.
hero member
Activity: 672
Merit: 500
I can't bet anymore, I keep getting internal server errors.
full member
Activity: 196
Merit: 100
and also then limit it to 32*8 bit for the user to enter (instead of unlimited). So the user can enter ANYTHING and is not limited by the site operator.
hero member
Activity: 672
Merit: 500
Just made a deposit, I can't gamble though. First it said something about the seed, now I get an error saying : Secret hash does not match the value on the server
EDIT: Works now after refreshing! I accidentally did a bet of 1.18 mBTC on <10, and it <10. Sorry, I'm hurting your bankroll :S I hope the max bet gets increased in the future.
full member
Activity: 196
Merit: 100
where a nonce should actually increment the data, not be appended to it.

Tell the Bitcoin developers about that. They just append the nonce in the header.
jr. member
Activity: 34
Merit: 1
Or you allow people to allow ANY string at all, then take the hash of your secret concatenated with whatever the user typed in. Then the user can type in his nice 100 character unicode string which you cannot possibly predict and everyone is happy.

We could do this, but a limit has to placed somewhere, what happens when someone wants to nonce it with a 100MB string, the service would have to parse and store it for an amount of time, while consuming precious resources. 32 bits offers 4.29 billion possibilities. Which should be enough for now. 

Also we don't currently do string concatenation for calculating the results, everything is done in raw byte format. I've seen many services that use the + operator on strings to concatenate, where a nonce should actually increment the data, not be appended to it.
full member
Activity: 196
Merit: 100
Still not amazingly solid (Like you claim in your OP), just means you might have to go through 10,000 server seeds opposed to 100 to find one with a high level of inconsistency.

Just do what JD does.

I've upped it to 32 bits, 4294967296 possibilities for the nonce, which should be enough for now. I'm not sure how well javascript would handle anything larger than 32-bit integers, so I'll have to test and see about increasing it.

I don't want to change to a high/low method as that would mean an API structure change. Besides JD could just as easily notice that you bet low most of the time and create a secret which is more likely to give high outputs, or that you bet high so they could make a low secret.

Secrets are chosen at random by the server, because they're computationally easier to generate that way than to pick a number, see if what sort of result it provides against a 16 or 32 bit nonce and then publish. Any method of pre-generating secrets is now computationally impractical, without using an ASIC for it. Even then, on a 5GHash machine, we'd only be able to generate 1 full secret profile after it has been nonced per second.

Or you allow people to allow ANY string at all, then take the hash of your secret concatenated with whatever the user typed in. Then the user can type in his nice 100 character unicode string which you cannot possibly predict and everyone is happy.
jr. member
Activity: 34
Merit: 1
Still not amazingly solid (Like you claim in your OP), just means you might have to go through 10,000 server seeds opposed to 100 to find one with a high level of inconsistency.

Just do what JD does.

I've upped it to 32 bits, 4294967296 possibilities for the nonce, which should be enough for now. I'm not sure how well javascript would handle anything larger than 32-bit integers, so I'll have to test and see about increasing it.

I don't want to change to a high/low method as that would mean an API structure change. Besides JD could just as easily notice that you bet low most of the time and create a secret which is more likely to give high outputs, or that you bet high so they could make a low secret.

Secrets are chosen at random by the server, because they're computationally easier to generate that way than to pick a number, see if what sort of result it provides against a 16 or 32 bit nonce and then publish. Any method of pre-generating secrets is now computationally impractical, without using an ASIC for it. Even then, on a 5GHash machine, we'd only be able to generate 1 full secret profile after it has been nonced per second.
full member
Activity: 196
Merit: 100
There's only 65536 different nonces a user can apply. You give the users secrets which when all those different nonces are applied, has a higher average, or more losses depending on the game they're playing. This will inherently change the odds advertised.

The secret is given out before the player chooses a number to play on, so is your concern that we could only chose secrets which were more likely end up with a high number when being nonced with every number in the range 1-65536? This is certainly possible, but computationally impractical.

In our tests performing dsha256(secret + nonce), where nonce is in the range 1-65536 gave quite an evenly random distribution. If necessary we can increase the size of the nonce field, maybe 32-bits would provide a more even distribution.

Edit: Valid point. I'll increase the size of the nonce.
Edit again: Nonce fields are now 32 bits, this is working in the api, but the html and javascript are cached and will clear in the browser after an hour.

Still not amazingly solid (Like you claim in your OP), just means you might have to go through 10,000 server seeds opposed to 100 to find one with a high level of inconsistency.

Just do what JD does.

But instead of having to hash 0xffff strings to find out which one has a high chance of winning for the house he would have to do 0xffffffff now. Which is practically impossible to do at this speed.
hero member
Activity: 504
Merit: 500
There's only 65536 different nonces a user can apply. You give the users secrets which when all those different nonces are applied, has a higher average, or more losses depending on the game they're playing. This will inherently change the odds advertised.

The secret is given out before the player chooses a number to play on, so is your concern that we could only chose secrets which were more likely end up with a high number when being nonced with every number in the range 1-65536? This is certainly possible, but computationally impractical.

In our tests performing dsha256(secret + nonce), where nonce is in the range 1-65536 gave quite an evenly random distribution. If necessary we can increase the size of the nonce field, maybe 32-bits would provide a more even distribution.

Edit: Valid point. I'll increase the size of the nonce.
Edit again: Nonce fields are now 32 bits, this is working in the api, but the html and javascript are cached and will clear in the browser after an hour.

Still not amazingly solid (Like you claim in your OP), just means you might have to go through 10,000 server seeds opposed to 100 to find one with a high level of inconsistency.

Just do what JD does.
full member
Activity: 196
Merit: 100
Edit again: Nonce fields are now 32 bits, this is working in the api, but the html and javascript are cached and will clear in the browser after an hour.

A shift+F5 fixed it for me.
Pages:
Jump to: