The algorithm for mining bitcoin in Python

This article describes a python implementation of bitcoin mining that relies on an algorithm based on a double hash SHA-256.

Introduction – Principle of the bitcoin mining agorithm

Miners on the bitcoin network should look for the nonce which is a 32-bit number. The miner will successively test several NONCEs (1,2,3 …. 10 ^ 32-1), for each of the nonce he creates the following header and hasher twice with a SHA-256 bit hash function.

FieldDescriptionSize
versionVersion 4
Hash previous block256-bit hash of the previous block32
Merkle rootThis is a hash on the data in the block. It is provided to the miner and it contains a summary of the transactions that are contained in the block.32
timeA digital timestamp that represents the number of seconds since 1970-01-01T00: 00 UTC4
bitsThe current target in compacted format4
nonce32-bit number (starts at 0)4

Once the hash obtained, the miner must then check that the hash obtained is lower than the target difficulty factor of the block. If the hash obtained is greater then the nonce is not the correct one, another must be tested.

Example on block 671712

If you are using a blockhain bitoin explorer (for example blocstream info), if we take for example block 671712:

Website blockstream.info

In this case here is an algorithm in python which allows to mine this block:

In this simulation I display the header and the calculated hash as well as the hash rate.

The nonce to find for block 671712 was 4107802144

in hexadecimal : 0xf4d81620

This algorithm starts with a nonce = 4107802144 – 400 we will act as if we were very close to finding the block (400 double hashes are missing to find the block):

import hashlib
from hashlib import sha256
import time
import struct
import binascii
import datetime
from binascii import unhexlify, hexlify
from dateutil import parser
from datetime import datetime
from datetime import timedelta 

nontrouve = True
dtprec = datetime.now()
inonc = 4107802134 - 400 #Starting 400 before the good nonce
resultat = []

while(nontrouve):
    inonc +=1
    if(inonc%50==0):
        print(str(round(timedelta(seconds=1)/(datetime.now() - dtprec))) + ' H/s')
    dtprec = datetime.now()
    header_hex = (binascii.hexlify(struct.Struct('<L').pack(int('0x2fffe000',16))).decode()  + 
     binascii.hexlify(binascii.unhexlify('000000000000000000078908d256fa7a9f97b2e1ea532fb1ce45ee4bf050d221')[::-1]).decode()+
     binascii.hexlify(binascii.unhexlify('c504fc3a406f11c7c5b598da7f50916f4e298041e6f9b91535a80db113af109a')[::-1]).decode() +
     binascii.hexlify(struct.Struct('<L').pack(int(hex(int(parser.parse('2021-02-22 15:14:22 GMT +1').timestamp())-3600),16))).decode() +
     binascii.hexlify(struct.Struct('<L').pack(int("0x170cf4e3",16))).decode() + 
     binascii.hexlify(struct.Struct('<L').pack(int(hex(inonc),16))).decode()) 
    header_bin = unhexlify(header_hex)
    dt1 = datetime.now().strftime("%H:%M:%S.%f")
    hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
    hexlify(hash).decode("utf-8")
    hexlify(hash[::-1]).decode("utf-8")
    hash=hexlify(hash[::-1]).decode("utf-8") 
    resultat.append([round(int(hash,16)/10**65)])
    
    MAX_TARGET = int("00000000FFFF0000000000000000000000000000000000000000000000000000", 16)           
    Difficulty = 21724134900047.27                     
    target = int(MAX_TARGET / Difficulty)
    target32 = '{:0>64x}'.format(target)    
    if(int(hash,16) < int(target32,16)):
        print('###########BLOC MINED###################')
        print('HEADER=' + header_hex)
        print('HASH=' + hash)
        print('NONCE=' + str(inonc))
        print('NONCE (hex)=' + hex(inonc))
        print('###########BLOC MINED###################')
        break

The output is :

1149 H/s
4405 H/s
4115 H/s
1534 H/s
3831 H/s
2392 H/s
4386 H/s
3165 H/s
###########BLOC MINED###################
HEADER=00e0ff2f21d250f04bee45ceb12f53eae1b2979f7afa56d20889070000000000000000009a10af13b10da83515b9f9e64180294e6f91507fda98b5c5c7116f403afc04c53ebc3360e3f40c172016d8f4
HASH=000000000000000000062a949bc297739a12e639ba9e2107638b469afe11d0f8
NONCE=4107802144
NONCE (hex)=0xf4d81620
###########BLOC MINED###################

External link- bitcoin mining with python

https://en.bitcoin.it/wiki/Block_hashing_algorithm

Internal link – bitcoin algorithm python

https://128mots.com/index.php/2020/03/30/construire-une-application-decentralisee-full-stack-pas-a-pas-ethereum-blockchain-dapp-en-plus-de-128-mots-partie-1/

L’algorithme pour miner le bitcoin en Python

Cet article décrit une implémentation en python du minage du bitcoin qui s’appuie sur un algorithme basé sur un double hash SHA-256.

Introduction – Principe de l’agorithme de minage du bitcoin

Les mineurs du réseau bitcoin doivent rechercher le nonce qui est un un nombre de 32 bits. Le mineur va tester successivement plusieurs NONCE (1,2,3 ….10^32-1), pour chacun des nonce il crée l’entête suivante et le hasher 2 fois avec une fonction de hachage SHA-256 bits.

FieldDescriptionSize
versionVersion 4
Hash du bloc précédent256-bit hash du block précédent32
Merkle rootIl s’agit d’un hash sur les données du bloc. Il est fournit au mineur et il contient un résumé des transactions qui sont contenues dans le bloc. 32
timeUn timestamp numérique qui représente le nombre de seconde depuis 1970-01-01T00:00 UTC4
bitsLa cible actuelle (Current target) en format compacté4
nonce32-bit number (starts at 0)4

Une fois le hash obtenu le mineur doit ensuite vérifier que le hash obtenu est inférieur au facteur de difficulté cible du bloc. Si le hash obtenu est supérieur alors le nonce n’est pas le bon il faut en tester un autre.

Exemple sur le bloc 671712

Si vous utilisez un explotateur de blochain bitoin (par exemple blocstream info), si on prends par exemple le bloc 671712 :

Website blockstream.info

Dans ce cas voici un algorithme en python qui permet de miner ce bloc :

Dans cette simulation j’affiche le header et le hash calculé ainsi que le hash rate.

Le nonce a trouver pour le bloc 671712 était 4107802144

Soit en hexa : 0xf4d81620

Cette algorithme démarre avec un nonce = 4107802144 – 400 nous allons faire comme si on était à très proche de trouver le bloc (il manque 400 double hash à effectuer pour trouver le bloc) :

import hashlib
from hashlib import sha256
import time
import struct
import binascii
import datetime
from binascii import unhexlify, hexlify
from dateutil import parser
from datetime import datetime
from datetime import timedelta 

nontrouve = True
dtprec = datetime.now()
inonc = 4107802134 - 400 #Starting 400 before the good nonce
resultat = []

while(nontrouve):
    inonc +=1
    if(inonc%50==0):
        print(str(round(timedelta(seconds=1)/(datetime.now() - dtprec))) + ' H/s')
    dtprec = datetime.now()
    header_hex = (binascii.hexlify(struct.Struct('<L').pack(int('0x2fffe000',16))).decode()  + 
     binascii.hexlify(binascii.unhexlify('000000000000000000078908d256fa7a9f97b2e1ea532fb1ce45ee4bf050d221')[::-1]).decode()+
     binascii.hexlify(binascii.unhexlify('c504fc3a406f11c7c5b598da7f50916f4e298041e6f9b91535a80db113af109a')[::-1]).decode() +
     binascii.hexlify(struct.Struct('<L').pack(int(hex(int(parser.parse('2021-02-22 15:14:22 GMT +1').timestamp())-3600),16))).decode() +
     binascii.hexlify(struct.Struct('<L').pack(int("0x170cf4e3",16))).decode() + 
     binascii.hexlify(struct.Struct('<L').pack(int(hex(inonc),16))).decode()) 
    header_bin = unhexlify(header_hex)
    dt1 = datetime.now().strftime("%H:%M:%S.%f")
    hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
    hexlify(hash).decode("utf-8")
    hexlify(hash[::-1]).decode("utf-8")
    hash=hexlify(hash[::-1]).decode("utf-8") 
    resultat.append([round(int(hash,16)/10**65)])
    
    MAX_TARGET = int("00000000FFFF0000000000000000000000000000000000000000000000000000", 16)           
    Difficulty = 21724134900047.27                     
    target = int(MAX_TARGET / Difficulty)
    target32 = '{:0>64x}'.format(target)    
    if(int(hash,16) < int(target32,16)):
        print('###########BLOC MINED###################')
        print('HEADER=' + header_hex)
        print('HASH=' + hash)
        print('NONCE=' + str(inonc))
        print('NONCE (hex)=' + hex(inonc))
        print('###########BLOC MINED###################')
        break

La sortie est la suivante :

1149 H/s
4405 H/s
4115 H/s
1534 H/s
3831 H/s
2392 H/s
4386 H/s
3165 H/s
###########BLOC MINED###################
HEADER=00e0ff2f21d250f04bee45ceb12f53eae1b2979f7afa56d20889070000000000000000009a10af13b10da83515b9f9e64180294e6f91507fda98b5c5c7116f403afc04c53ebc3360e3f40c172016d8f4
HASH=000000000000000000062a949bc297739a12e639ba9e2107638b469afe11d0f8
NONCE=4107802144
NONCE (hex)=0xf4d81620
###########BLOC MINED###################

Lien externe – minage de bitcoin en python

https://en.bitcoin.it/wiki/Block_hashing_algorithm

Lien interne

https://128mots.com/index.php/2020/03/30/construire-une-application-decentralisee-full-stack-pas-a-pas-ethereum-blockchain-dapp-en-plus-de-128-mots-partie-1/

Android SDK Exception in thread « main » java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema

When you try to lauchn the utility sdkmanager for android SDK you get the following error : Exception in thread « main » java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema

How to solve this error ?

Solution is to install JDK 8 :

brew cask uninstall java
brew tap homebrew/cask-versions
brew cask install java8
touch ~/.android/repositories.cfg
brew cask install android-sdk

In some case the right command is :

brew install openjdk@8
https://128mots.com/index.php/2021/02/15/implementation-des-graphes-en-python/

Website formulae.brew.sh

modules/speech_to_text/register_types.cpp:2:10: fatal error: ‘object_type_db.h’ file not found – GODOT Compilation

If you get this error modules/speech_to_text/register_types.cpp:2:10: fatal error: ‘object_type_db.h’ file not found you need to do this :

Introduction – modules/speech_to_text/register_types.cpp:2:10: fatal error: ‘object_type_db.h’ file not found

Go into directory source of GODOT and modules/speech_to_text :

File to open is register_types.cpp

You will see use of a header file

#include "object_type_db.h"

It changes between GODOT 2 and 3 from object_type_db.h to class_db.h

So chang it by :

#include "core/object/class_db.h"

Save and execute GODOT source compilation again it will works.

I get similar error on

modules/speech_to_text/stt_config.h:4:10: fatal error: ‘core/resource.h’ file not found

You need to open modules/speech_to_text/stt_config.h and modify :

#include "core/resource.h"

By :

#include "core/io/resource.h"

Also i get modules/speech_to_text/stt_error.h:4:10: fatal error: ‘core/object.h’ file not found

so i do the following in stt_error.h :

#include "core/object.h"
#include "core/ustring.h"
#include "core/object/object.h"
#include "core/string/ustring.h"

Internal links :

https://128mots.com/index.php/en/2021/02/17/typeerror-can_build-takes-1-positional-argument-but-2-were-given/

Website docs.godotengine.org

TypeError: can_build() takes 1 positional argument but 2 were given – Godot Compilation

If you get this type of errors TypeError: can_build() takes 1 positional argument but 2 were given when trying to compile Godot you have to do this :

When i tried to compile with scons i got this errors :

scons: Reading SConscript files ...
Automatically detected platform: osx
Building for macOS 10.12+, platform x86-64.
TypeError: can_build() takes 1 positional argument but 2 were given:
  File "/Users/myuser/godot/SConstruct", line 556:
    if config.can_build(env, selected_platform):

How to solve this error ?

First check you version of scons by launching :

scons -v

It will give you the scons path :

SCons path: ['/usr/local/Cellar/scons/4.1.0.post1/libexec/lib/python3.9/site-packages/SCons']

You then notice the use of python 3.9

You have to update your python to 3.9 :

Update Python easy update to Python 3.9 with homebrew – To update Mac os python from an older version to the latest python example python 3.9.1 you can do the folowing :

This article briefly describes how to replace its version of python on Mac. I wrote a similar article some time ago.

I used Homebrew to get the latest python as describe on Website formulae.brew.sh:

brew install python@3.9
python --version
Python 3.8.5
python3 --version
Python 3.8.5

You see that it stays on the older version.

Detect where python or python3 is setup

I had to first verify where my python command is pointing, by launching :

which python

It gave me in my case:

/Users/myuser/.pyenv/shims/python

You need also to verify where is python3 command if you have different versions :

which python3  

I get :

/Users/myuser/.pyenv/shims/python3

Replace the version

I need to replace the version of the both command python and python3 by launching :

ln -s -f /usr/local/bin/python3.9 /Users/myuser/.pyenv/shims/python3

And also launch :

ln -s -f /usr/local/bin/python3.9 /Users/myuser/.pyenv/shims/python

The you can test it works :

python --version 
Python 3.9.1
python3 --version 
Python 3.9.1

Come back on GODOT compilation with Scons :

You need to localize the module that is bad in GODOT modules directory

For example i localize speech_to_text that was bad in config.py

So i directly modify config.py from this directory from can_build(env) to can_build(env, platform):

import os  # system()


def can_build(env, platform):
    if platform == "x11":
        has_pulse = os.system("pkg-config --exists libpulse-simple") == 0
        has_alsa = os.system("pkg-config --exists alsa") == 0
        return has_pulse or has_alsa
    elif platform in ["windows", "osx", "iphone", "android"]:
        return True
    else:
        return False


def configure(env):
    pass

And it works :

godot % scons
scons: Reading SConscript files ...
Automatically detected platform: osx
Building for macOS 10.12+, platform x86-64.
YASM is necessary for WebM SIMD optimizations.
WebM SIMD optimizations are disabled. Check if your CPU architecture, CPU bits or platform are supported!
Checking for C header file mntent.h... no
scons: done reading SConscript files.
scons: Building targets ...
[Initial build] Compiling ==> platform/osx/crash_handler_osx.mm
[Initial build] Compiling ==> platform/osx/os_osx.mm
[Initial build] Building RD_GLSL header: "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h"
[Initial build] Building RD_GLSL header: "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h"
[Initial build] Building RD_GLSL header: "servers/rendering/renderer_rd/shaders/scene_forward.glsl.gen.h"
[Initial build] Building RD_GLSL header: "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"

TypeError: can_build() takes 1 positional argument but 2 were given – Internal links :

This article briefly describes how to replace its version of python on Mac. I wrote a similar article some time ago.

https://128mots.com/index.php/2021/02/15/implementation-des-graphes-en-python/

Mac os update Python easy update to Python 3.9 with homebrew

Update Python easy update to Python 3.9 with homebrew – To update Mac os python from an older version to the latest python example python 3.9.1 you can do the folowing :

This article briefly describes how to replace its version of python on Mac. I wrote a similar article some time ago.

Introduction – update to Python 3.9.1 – HOMEBREW

I used Homebrew to get the latest python as describe on Website formulae.brew.sh:

brew install python@3.9
python --version
Python 3.8.5
python3 --version
Python 3.8.5

You see that it stays on the older version.

Detect where python or python3 is setup

I had to first verify where my python command is pointing, by launching :

which python

It gave me in my case:

/Users/myuser/.pyenv/shims/python

You need also to verify where is python3 command if you have different versions :

which python3  

I get :

/Users/myuser/.pyenv/shims/python3

Replace the version

I need to replace the version of the both command python and python3 by launching :

ln -s -f /usr/local/bin/python3.9 /Users/myuser/.pyenv/shims/python3

And also launch :

ln -s -f /usr/local/bin/python3.9 /Users/myuser/.pyenv/shims/python

The you can test it works :

python --version 
Python 3.9.1
python3 --version 
Python 3.9.1

Mac os update Python – Internal links :

This article briefly describes how to replace its version of python on Mac. I wrote a similar article some time ago.

https://128mots.com/index.php/2021/02/15/implementation-des-graphes-en-python/

Implémentation des graphes en Python – Exemple BFS

Implémentation des graphes en Python par l’exemple : Le parcours en largeur python d’un graphe (BFS) est un algorithme utilisé pour parcourir les structures de donnée de graphe. BFS met en œuvre une stratégie spécifique pour visiter tous les sommets d’un graphe.

Introduction – Implémentation des graphes en Python

BFS commence par un sommet, puis il vérifie les voisins du sommet initial, puis les voisins des voisins, etc.

En entrée de l’algorithme il y a le graphe G et un sommet de départ D pour lequel on considère que la distance est 0.

En sortie de l’algorithme sont calculées toutes les distances entre le sommet D et chaque sommet du graphe G ainsi que l’arbre couvrant si le graphe G est connexe (c’est à dire que pour toute paire de sommet il existe un chemin entre eux dans le graphe).

Description de l’algorithme

On utilise les tableaux suivants :

  • Distance[.] : Stocke la distance entre D (sommet de départ) et un autre sommet du graphe.
  • Father[.] : Stocke le sommet père d’un sommet du graphe parcouru.
  • Visite[.] : Stocke l’état de visite du sommet, liste des valeurs possible 0:pas encore visité,1:Visite en cours,2:Visité

On utilise les fonctions suivantes pour une file F :

  • First(F) : Retourne l’élément en tête de la file F sans le supprimer.
  • Dequeue(F) : Retourne l’élément en tête de la file F en le supprimant.
  • Append(F, A) : Mettre l’élément A dans la file F en queue de la file.

Les étapes de l’algorithme :

  • Phase d’initialisation
    • 1. Pour tous les sommets faire
      • Visite = 0 (Pas encore visité)
      • Pere = null (Initialise le tableau)
      • Distance = -1
    • 2. Append(F,D) (ajoute l’élément de départ)
    • 3. Distance[R] = 0 (postulat de départ)
  • Phase d’action (parcours du graphe G)
    • Tant que la file F n’est pas vide
      • t = First(F)
      • Pour tous les voisins v de t faire
        • Si Visite[v] = 0 (sommet non visité) alors
          • Visite[v] = 1 (Visite en cours)
          • Distance[v] = Distance[t] + 1
          • Father[v] = t
          • Append(F,v)
      • Dequeue(F)
      • Visite[t] = 2

Si on détaille les étapes avec le cas du graphe exemple ci-dessous.

Phase d’initialisation :

Initialisation l’élément A est l’élément de départ à distance 0, il est coloré en orange pour indiquer que la visite est en cours.

Visite des voisins du sommet A (Visite du sommet B)

Le sommet B passe à en cours de visite, sa distance de A est calculée et le sommet A est ajouté comme sommet père. Il est ajouté à la file.

implémentation des graphes en python – Visite des voisins du sommet A (Visite du sommet C)

Le sommet C passe à en cours de visite, sa distance de A est calculée et le sommet A est ajouté comme sommet père. Il est ajouté à la file.

Marquage de A comme visité et suppression de la file

A est marqué comme visité (couleur bleue) et retiré de la tête de la file

Visite des voisins du sommet B (Visite du sommet D)

Le sommet C etant marqué comme en cours de visite il ne sera pas visité, on visite le sommet D on calcule sa distance = 2 et on note le sommet B comme père du sommet B.

Marquage de B et C comme visité et suppression de la file

B est marqué comme visité (couleur bleue) et retiré de la tête de la file
C est marqué comme visité (couleur bleue) et retiré de la tête de la file (son voisin D est marqué en cours de visite)

Marquage de D comme visité et fin de l’algorithme

D est marqué comme visité (couleur bleue) et retiré de la tête de la file.
Fin de l’algorithme

Construction de l’arbre couvrant si le graphe est connexe

Si le graphe est connexe on déplie le résultat du parcours et on obtient l’arbre couvrant du graphe qui contient tous les sommets.

Application : Le parcours en largeur d’un graphe (BFS) est utile pour :

  • Vérifier si un graphe est connexe (tous les sommets sont alors marqués comme visités à la fin de l’algorithme).
  • Calculer les distances à partir d’un sommet donné
  • Construire un arbre couvrant du graphe
from collections import deque
def bfs(graph, vertex):
    queue = deque([vertex])
    distance = {vertex: 0}
    pere = {vertex: None}
    while queue:
      t = queue.popleft()
      for voisin in graph[t]:
        if voisin not in distance:
          queue.append(voisin)
          distance[voisin] = distance[t] + 1
          pere[voisin] = t
    return distance, pere
#Liste d'ajacence du graphe
graph = {
  'A': ['B','C'],
  'B': ['A','C', 'D'],
  'C': ['D'],
  'D': ['C','A']
}
distance,pere = bfs(graph,'A')
print("Distances" + str(distance))
print("Pere = " + str(pere))

Parcours en largeur python – Liens externes

Website fr.wikipedia.org

Website www.python.org

Website fr.wikipedia.org

Implémentation des graphes en python – Liens internes

https://128mots.com/index.php/category/python/

https://128mots.com/index.php/2021/01/21/algorithme-glouton-python/

Comment faire un ping sur Filius ?

Comment faire un ping sur Filius ? Filius est un logiciel de simulation de réseau. Ce premier article présente la création d’un réseau ad hoc entre deux ordinateurs et l’utilisation la commande ping.

Etape 1 :

Ajouter les 2 ordinateurs et les relier par un câble réseau.

Filius configuration d’un réseau de 2 ordinateurs

Etape 2 :

Configurer le nom et l’adresse IP des ordinateurs, soit « Ordinateur A » : 198.168.0.10 et « Ordinateur B » : 198.168.0.20

Etape 3 :

Démarrer et installer la ligne de commande sur l’ordinateur A en cliquant dessus.

FIlius installation de la ligne de commande sur ordinateur A

Etape 4 :

Utiliser la commande ping 192.168.0.20. Ping est une commande qui envoie des paquets réseau vers l’adresse demandée et qui mesure les temps de réponse.

Commande ping

Filius ping – Liens Externes

Website www.ionos.fr

Website fr.wikipedia.org

Website www.cisco.com

Filius ping -Liens Internes

https://128mots.com/index.php/en/category/non-classe-en/

https://128mots.com/index.php/category/non-classe/

https://128mots.com/index.php/2021/01/26/ordinateur-quantique-prix/
Si vous êtes un passionné de jeux vidéo en ligne, découvrez des astuces pour réduire le ping et améliorer votre expérience de jeu dans cet article utile