-
-
Save NostrCasino/9eda61f2244d2bf0327379d8d92cd24e to your computer and use it in GitHub Desktop.
verifiable_coinflip.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
coinflip@nostrcasino.com, the quickest way to to double your sats on Nostr! | |
npub: npub179afcatzjjex3zm3ya04xzg55cqzeklakw0atcstwlygujh88scsuyvgjy | |
You can verify the fairness and result of the coinflip from this python | |
script. | |
In order to ensure it's a fair flip, we follow the following protocol: | |
1. You start a game by posting `@coinflip num_sats` | |
2. We generate a seed, and share the hash of the seed (`seed_hash`) with you (along with a lightning invoice for num_sats) | |
3. You pay the invoice, then respond with 'heads' or 'tails' | |
4. We use the signature from your response (that we couldn't know ahead of time) | |
in the code below. | |
5. We share the seed with you (and your signature for convenience) | |
""" | |
import hashlib | |
import hmac | |
# fill in the following variables from your game | |
seed_hash = ... # shared in step 2 | |
seed = ... # shared in step 5 | |
signature = ... # shared in step 5 | |
player_guess = ... # either "heads" or "tails", provided by you in step 3 | |
# first, verify that the seed_hash really comes from the seed | |
def verify_seed_hash(seed, seed_hash): | |
computed_seed_hash = hashlib.sha256(seed).hexdigest() | |
if seed_hash == computed_seed_hash: | |
print("We verified that the seed_hash comes from the seed!") | |
else: | |
print("The seed_hash does not come from the seed, something is wrong!") | |
# next, verify the result of the coinflip | |
def heads_or_tails(seed, signature, player_guess): | |
precision = 12 | |
house_edge = 0.0099 # 0.99% house edge | |
signature_bytes = bytes.fromhex(signature) | |
computed_hmac = hmac.new(signature_bytes, msg=seed , digestmod=hashlib.sha512).hexdigest() | |
hmac_substring = computed_hmac[precision - 1::-1] # take a subset of the computed hmac | |
assert len(hmac_substring) == precision | |
int_result = int.from_bytes(bytes.fromhex(hmac_substring), byteorder="big", signed=True) + 0.5 | |
normalized_result = int_result / 16 ** precision # normalize result between (-0.5, 0.5) | |
if player_guess == "heads": | |
normalized_result -= house_edge | |
else: | |
normalized_result += house_edge | |
if normalized_result > 0: | |
final_result = "heads" | |
else: | |
final_result = "tails" | |
print(f"the result of the coinflip is {final_result}!") | |
# The following 2 steps verify that it was a fair coin flip! | |
verify_seed_hash(seed, seed_hash) | |
heads_or_tails(seed, signature, player_guess) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment