Bitcoin Forum
May 03, 2024, 10:12:57 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 [2]  All
  Print  
Author Topic: solomining probability calculator  (Read 337 times)
akaki
Newbie
*
Offline Offline

Activity: 22
Merit: 35


View Profile
February 05, 2023, 10:43:56 AM
Last edit: February 05, 2023, 01:01:20 PM by akaki
 #21

the correct answer in my opinion is

1- [chance with 50 PH/s for 3h] = [chance with 25 PH/s for 6h] = [chance with 5 PH/s for 30h]

because it takes into account the shares submitted.

The problem can be generalized to :

is [chance with x bets in n attempts] = or > [chance with x/y bets in y*n attempts] ?

My answer is based on these extreme case examples :

1) Alice bets on the 6 numbers of the dice and rolls it 1 time  --> Alice is 100% sure of hitting a number

2) Bod bets on 1 number of the dice but rolls it 6 times          --> Bob may not hit a number (even if he bets on the same number). But he is "expected" to hit a number if he increases the number of his attempts.

For me this is why strictly speaking [chance with x bets in n attempts] > [chance with x/y bets in y*n attempts] .

3) Let's assume that Bob bets always on the same number    --> The probability of hitting this number at least one = 66.5% in 6 rolls or = 98.7% in 24 rolls (1-(5/6)^n for the formula).

In the case of bitcoin mining, the winning number is new every 10 min. Then what matters is the available hash rate during these 10 min.

The discussion is interesting, I'll be glad of hearing clarifications from experts.
1714774377
Hero Member
*
Offline Offline

Posts: 1714774377

View Profile Personal Message (Offline)

Ignore
1714774377
Reply with quote  #2

1714774377
Report to moderator
1714774377
Hero Member
*
Offline Offline

Posts: 1714774377

View Profile Personal Message (Offline)

Ignore
1714774377
Reply with quote  #2

1714774377
Report to moderator
1714774377
Hero Member
*
Offline Offline

Posts: 1714774377

View Profile Personal Message (Offline)

Ignore
1714774377
Reply with quote  #2

1714774377
Report to moderator
Once a transaction has 6 confirmations, it is extremely unlikely that an attacker without at least 50% of the network's computation power would be able to reverse it.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
paid2
Hero Member
*****
Offline Offline

Activity: 686
Merit: 2052


Crypto Swap Exchange


View Profile WWW
February 15, 2023, 08:52:19 PM
 #22

Hey OP !

Here is the French translation :

Code:
#!/usr/bin/env python3
##########################################
#         2023/Jan/28 by citb0in         #
#       https://github.com/citb0in       #
#                                        #
#   This project is licensed under the   #
#       terms of the GPLv3 license.      #
##########################################
import requests
import re

####################
# Some global vars #
####################

# Uncomment following line(s) for manually seting the difficulty/netrate to a value of your choice
#diff = 210453655497.094
#netrate = 1510000000000000000

# Number of chars to print as horizontal line separator, on a widescreen you could try 200
sep = 150

###########################
# Definitions (functions) #
###########################

def get_diff_and_netrate(diff_from_api=False,netrate_from_api=False):
    """Function for getting the current Bitcoin difficulty and network hashrate from API"""
    global diff
    global netrate
    if 'diff' not in globals() or 'netrate' not in globals():
        response = requests.get("https://mempool.space/api/v1/mining/hashrate/3d")
        print("Execution de la requête API pour recevoir les informations du réseau Bitcoin...\n")
        if response.status_code != 200:
            raise Exception("Èchec, impossible de recevoir les données depuis API")
        if 'diff' not in globals():
            diff = response.json()["currentDifficulty"]
            diff_from_api = True
        if 'netrate' not in globals():
            netrate = response.json()["currentHashrate"]
            netrate_from_api = True
    return diff, netrate, diff_from_api, netrate_from_api

def get_probability_single_hash():
    """Function to calculate the probability of a single hash solving a block"""
    # the target represents the number of valid hashes
    # ratio of all hashes over valid hashes => 2**256 / (0xffff*2**208 / D)
    ratio = diff * 2**48 / 0xffff
    prob = 1/ratio
    return ratio, prob

def get_proportion_of_netrate(hashrate):
    """Function to set the hashrate of the solominer in relation to the total network rate"""
    proportion = hashrate_raw / netrate * 100
    if "e-" in str(proportion):
        precision = 1
        netrate_prec = int(str(proportion).split("e-")[1]) + precision
    else:
        netrate_prec = re.search(r"[1-9]", str(proportion)).start()
    return proportion, netrate_prec

def format_input(hashrate_raw):
    """Function for formatting the input hashrate"""
    hashrate_match = re.match(r'^\s*([0-9]+(?:\.[0-9]+)?)\s*([KMGTPEZY]?)\s*(H)?\s*(\/)?\s*(s|sec)?\s*$', hashrate_raw, flags=re.IGNORECASE)
    if hashrate_match:
        hashrate_nounit = float(hashrate_match.group(1))
        hashrate_unit = hashrate_match.group(2).upper()
        conversions = {'K': 1e3, 'M': 1e6, 'G': 1e9, 'T': 1e12, 'P': 1e15, 'E': 1e18, 'Z': 1e21, 'Y': 1e24}
        if hashrate_unit in conversions:
            hashrate_raw = hashrate_nounit*conversions[hashrate_unit]
        else:
            hashrate_raw = hashrate_nounit
    else:
        return None
    return hashrate_nounit, hashrate_unit, hashrate_raw

def scale_unit(value):
    """Function for scaling to highest possible unit"""
    units = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
    value = str(value)
    prefix = ''
    if ' ' in value:
        value, prefix = value.split()
    exponent = 0
    while float(value) >= 1000:
        value = str(float(value) / 1000)
        exponent += 1
    return f"{float(value):.2f} {units[exponent]}{prefix}"

def calculate_probability(hashrate):
    """Function for calculating the probability per block avg. time of 10min for use as a base"""
    expected_blockhit_time = diff * 2**48 / 0xffff / hashrate_raw / 3600
    expected_blockhit_rel_net = netrate / hashrate_raw * 600
    prob_per_10min = hashrate_raw / (diff * 2**48 / 0xffff) * 600
    prob_per_block = prob_per_10min
    if "e-" in str(prob_per_10min):
        # Number of desired additional decimal places
        # beginning from first occurring decimal place not equal to zero
        precision = 2
        prob_prec = int(str(prob_per_10min).split("e-")[1]) + precision
    else:
        prob_prec = 3
    # Define some additional time units
    prob_per_hour = prob_per_block * 6
    prob_per_day = prob_per_hour * 24
    prob_per_week = prob_per_day * 7
    prob_per_month = prob_per_day * 30
    prob_per_halfyear = prob_per_day * 182.5
    prob_per_year = prob_per_day * 365
    return expected_blockhit_time, expected_blockhit_rel_net, prob_per_block, prob_per_hour, prob_per_day, prob_per_week, prob_per_month, prob_per_halfyear, prob_per_year, prob_prec, netrate_prec

def probability_phrase(probability):
    if probability <= 0.00001:
        return "plus de chances d'être frappé par un éclair"
    elif probability <= 0.0001:
        return "plus de chances de gagner au Lotto"
    elif probability <= 0.45:
        return "les chances sont contre vous en théorie"
    elif probability <= 0.55:
        return "aussi probable que de tirer à pile ou face et d'obtenir face."
    elif probability <= 0.00001:
        return "plus probable que de trouver une aiguille dans une botte de foin."
    elif probability <= 0.001:
        return "aussi probable que de faire un trou en un au golf."
    elif probability <= 0.000001:
        return "probabilité similaire à celle de trouver un grain de sable spécifique sur une plage"
    elif probability <= 0.001:
        return "aussi probable que d'obtenir un score parfait à un jeu de fléchettes."
    elif probability <= 0.5:
        return "improbable"
    else:
        return "plus probable que non"

def describe_probability(prob):
    if prob >1:
        return "une garantie, une chose sûre à 100% - vous pouvez parier votre dernier dollar là-dessus. Ça va arriver bientôt ! YEAH ! !!"
    if prob >= 0.99 and prob <= 1:
        return "pratiquement certain, presque une garantie - c'est similaire à la probabilité que le soleil se lève demain."
    elif prob >= 0.98 and prob < 0.99:
        return "extrêmement probable, presque une certitude - c'est similaire à la probabilité qu'une équipe de football gagne un match lorsqu'elle mène de 14 points à 2 minutes de la fin."
    elif prob >= 0.95 and prob < 0.98:
        return "très probable, hautement probable - c'est similaire à la probabilité qu'un lanceur de baseball lance un strike avec un compte de 3-2."
    elif prob >= 0.9 and prob < 0.95:
        return "C'est un peu comme la probabilité qu'un golfeur fasse un putt d'un mètre cinquante."
    elif prob >= 0.8 and prob < 0.9:
        return "plus probable que non - c'est similaire à la probabilité qu'une équipe de basket-ball réussisse un lancer franc."
    elif prob >= 0.7 and prob < 0.8:
        return "C'est un peu comme la probabilité qu'une équipe de football marque un touchdown dans une zone rouge."
    elif prob >= 0.6 and prob < 0.7:
        return "C'est un peu comme la probabilité qu'une prévision météorologique annonce de la pluie et qu'il pleuve réellement."
    elif prob >= 0.5 and prob < 0.6:
        return "C'est un peu comme la probabilité de tirer à pile ou face et d'obtenir pile du premier coup."
    elif prob >= 0.4 and prob < 0.5:
        return "assez probable - elle est similaire à la probabilité de tirer une carte rouge d'un jeu de cartes à jouer standard"
    elif prob >= 0.3 and prob < 0.4:
        return "moins probable que non - c'est similaire à la probabilité qu'une équipe de baseball remporte un match alors qu'elle est menée par quatre points dans le bas de la neuvième manche."
    elif prob >= 0.2 and prob < 0.3:
        return "improbable, tout à fait improbable - c'est un peu comme la probabilité de deviner la bonne combinaison d'une serrure à trois chiffres du premier coup."
    elif prob >= 0.1 and prob < 0.2:
        return "très improbable, hautement improbable - c'est comme la probabilité d'obtenir un nombre spécifique en lançant un dé juste."
    elif prob >= 0.01 and prob < 0.1:
        return "Extrêmement improbable - c'est comme tirer à pile ou face et obtenir pile 10 fois de suite."
    elif prob >= 0.001 and prob < 0.01:
        return "pratiquement impossible - c'est comme lancer une pièce de monnaie et obtenir pile 100 fois de suite."
    elif prob >= 0.0001 and prob < 0.001:
        return "pratiquement impossible - il est plus probable d'être frappé par la foudre deux fois au même endroit ou de recevoir une quinte royale au poker dès la première main."
    elif prob >= 0.00005 and prob < 0.0001:
        return "pratiquement impossible - il est plus probable d'être frappé par la foudre dans une vie."
    elif prob >= 0.00001 and prob < 0.00005:
        return "pratiquement impossible - c'est comme si un individu donné était frappé par la foudre plusieurs fois dans sa vie."
    elif prob >= 0.000001 and prob < 0.00001:
        return "pratiquement impossible - c'est comme la probabilité de gagner un prix dans une loterie avec 1 chance sur 10 millions."
    elif prob >= 0.0000005 and prob < 0.000001:
        return "pratiquement impossible - c'est comme la probabilité d'obtenir une combinaison spécifique de cinq numéros sur une machine à sous."
    elif prob >= 0.00000005 and prob < 0.0000005:
        return "pratiquement impossible - il est plus probable de gagner le jackpot de la loterie Powerball ou Mega Millions."
    elif prob < 0.00000005:
        return "infiniment petit - c'est similaire à la probabilité de trouver un atome spécifique parmi tous les atomes de l'univers."
    else:
        return "discutable ? !"

#######################################
# Program flow / variable assignments #
#######################################

# User input hash rate
hashrate_input = input("Entrer le hashrate/sec de votre équipement solo : ")

# Call the functions and fill the variables
diff, netrate, diff_from_api, netrate_from_api = get_diff_and_netrate()
diff_formatted, netrate_formatted = scale_unit(diff), scale_unit(netrate)+"H/s"
hashrate_nounit, hashrate_unit, hashrate_raw = format_input(hashrate_input)
proportion, netrate_prec = get_proportion_of_netrate(hashrate_raw)
expected_blockhit_time, expected_blockhit_rel_net, prob_per_block, prob_per_hour, prob_per_day, prob_per_week, prob_per_month, prob_per_halfyear, prob_per_year, prob_prec, netrate_prec = calculate_probability(hashrate_raw)
single_ratio, single_prob = get_probability_single_hash()

##########
# Output #
##########

print(f"{'Choisir la difficulté manuellement:' if not diff_from_api else 'La difficulté actuelle de Bitcoin est :'} {diff:,.3f} ({diff_formatted})\n{'Hashrate total du réseau Bitcoin:' if not netrate_from_api else 'Le hashrate total de tout le réseau Bitcoin:'} {netrate:,.2f} ({netrate_formatted})\n")
print('\nLe ratio de tous les hash par rapport aux shares valides est de:\n1 hash sur {:,.0f}'.format(single_ratio),'donnera un block potentiellement valide.\nOu chaque hash a une chance de miner un block de {:,.30f} %'.format(single_prob))
print('=' * sep)
print(f'\nLe hashrate entré de {hashrate_nounit} {hashrate_unit}H/sec équivaut à: {hashrate_raw:,.2f} hash/sec\n Le ratio de votre hashrate par rapport au réseau BTC est de: {proportion:,.{netrate_prec}f} %\n')
print('=' * sep)
# Display probability as decimal value, percentage, "1 in x" format and as description / analogy text
print(f'Chances par 10 min: {prob_per_block:,.{prob_prec}f} ({prob_per_block*100:,.{prob_prec}f} %) ou 1 sur {1/prob_per_block:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {str(describe_probability(prob_per_block))}')
print('=' * sep)
print(f'Chances par heures: {prob_per_hour:,.{prob_prec}f} ({prob_per_hour*100:,.2f} %) ou 1 sur {1/prob_per_hour:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {int(round(1/prob_per_hour,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de  {str(describe_probability(prob_per_hour))}')
print('=' * sep)
print(f'Chances par jours: {prob_per_day:,.{prob_prec}f} ({prob_per_day*100:,.2f} %) ou 1 sur {1/prob_per_day:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant  {int(round(1/prob_per_day,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de  {str(describe_probability(prob_per_day))}')
print('=' * sep)
print(f'Chances par semaines: {prob_per_week:,.{prob_prec}f} ({prob_per_week*100:,.2f} %) ou 1 sur {1/prob_per_week:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant  {int(round(1/prob_per_week,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de  {str(describe_probability(prob_per_week))}')
print('=' * sep)
print(f'Chances par mois: {prob_per_month:,.{prob_prec}f} ({prob_per_month*100:,.2f} %) ou 1 sur {1/prob_per_month:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {int(round(1/prob_per_month,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de  {str(describe_probability(prob_per_month))}')
print('=' * sep)
print(f'Chances par demi-années: {prob_per_halfyear:,.{prob_prec}f} ({prob_per_halfyear*100:,.2f} %) ou 1 sur {1/prob_per_halfyear:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant  {int(round(1/prob_per_halfyear,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de  {str(describe_probability(prob_per_halfyear))}')
print('=' * sep)
print(f'Chances par années: {prob_per_year:,.{prob_prec}f} ({prob_per_year*100:,.2f} %) ou 1 sur {1/prob_per_year:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {int(round(1/prob_per_year,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de {str(describe_probability(prob_per_year))}')
print('=' * sep)
print(f'Temps attendu moyen pour miner un block :\n{expected_blockhit_time*3600:,.1f} sec = {expected_blockhit_time*60:,.1f} min = {expected_blockhit_time:,.1f} h = {expected_blockhit_time/24:,.1f} jours = {expected_blockhit_time/24/7:,.1f} semaines = {expected_blockhit_time/24/7/4.34:,.1f} mois = {expected_blockhit_time/24/7/4.34/12:,.1f} années\n')
print(f'Temps attendu moyen (en fonction de tout le réseau):\n{expected_blockhit_rel_net:,.1f} sec = {expected_blockhit_rel_net/60:,.1f} min = {expected_blockhit_rel_net/60/60:,.1f} h = {expected_blockhit_rel_net/60/60/24:,.1f} jours = {expected_blockhit_rel_net/60/60/24/7:,.1f} semaines = {expected_blockhit_rel_net/60/60/24/7/4.34:,.1f} mois = {expected_blockhit_rel_net/60/60/24/7/4.34/12:,.1f} années')
print('=' * sep)

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
Morguk
Hero Member
*****
Offline Offline

Activity: 594
Merit: 506



View Profile
April 09, 2023, 01:42:03 PM
 #23

Only skimmed the thread. Was there anything wrong with solochance in the end?

Calculate the chance of hitting a bitcoin block when solo mining at
citb0in (OP)
Hero Member
*****
Offline Offline

Activity: 658
Merit: 656


Bitcoin g33k


View Profile
April 09, 2023, 01:45:29 PM
 #24

don't get your question? What exactly you're asking for ?

.
.HUGE.
▄██████████▄▄
▄█████████████████▄
▄█████████████████████▄
▄███████████████████████▄
▄█████████████████████████▄
███████▌██▌▐██▐██▐████▄███
████▐██▐████▌██▌██▌██▌██
█████▀███▀███▀▐██▐██▐█████

▀█████████████████████████▀

▀███████████████████████▀

▀█████████████████████▀

▀█████████████████▀

▀██████████▀▀
█▀▀▀▀











█▄▄▄▄
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
.
CASINSPORTSBOOK
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀▀█











▄▄▄▄█
Pages: « 1 [2]  All
  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!