<jupyter_start><jupyter_text>Exemple de la preuve de travail (PoW ou Proof-of-Work)Ce document est un tutoriel éducatif sur la preuve de travail utilisée sur certaines technologies de chaîne de blocs.La preuve de travail est un moyen pour une autorité d'un système distribué (i.e. un noeud dans un écosystème à chaîne de blocs), d'ajouter un bloc de données à l'écosystème par la solution d'un casse-tête algorithmique difficile à trouver, mais dont le niveau de difficulté de la solution est prédéfinie.Courramment utilisé dans les chaînes de blocs énergivores, cette méthode d'autorisation d'ajout de données à l'écosystème permet entre autre aux machines-mineuses d'obtenir en retour une valeur en cryptomonnaie.Cette dernière n'est accordée qu'à la première machine-mineuse ayant :1. Ayant été la machine-mineuse la plus rapide pour trouver la solution2. Que cette solution ait été validé par par les autres machines-mineuses3. Que la solution du bloc soit confirmée par la plus longue chaîne Bitcoin en étant son pionnier (et suivi par Ethereum entre autres) utilise la preuve de travail pour neutraliser la puissance de destruction du système distribué de la chaîne de blocs, ou du moins, son écosystème.Accompagnée par les moyens cryptographiques de notre époque, la destruction de la base de données en chaîne de blocs distribué s'avère quasi impossible à en prendre le contrôle et en faire une fraude dans le registre.Trois points à tenir compte de ce que compose un écosystème à chaîne de blocs à la base :1. Le registre : en chaîne de blocs et son armure cryptographique2. Le noeud : mémoire et puissance de calcul, la machnine-mineuse3. Le consensus : qui défini la raison de l'écosystème pour valider ou rejeter un bloc de transactions dans l'écosystème4. La distribution : multiplicitée des noeuds pour éviter une attaque 50%+1 de pouvoir sur le réseau4. L'unité monnétaire digitale : essentiellement des structures de données de valeur en échange d'argent réel Vu que ce document éducatif fait uniquement une démonstration de la preuve de travail, je dédierai des documents séparés aux autres méthodes d'autorité d'un noeud de chaîne de blocs ainsi qu'aux autres points systémiques des chaînes de blocs selon leur écosystème.Nous n'en tenons seulement dans ce document à ce que défini la preuve de travail : trouver une solution d'un casse-tête d'un niveau de difficulté prédéfini.  Qu'est-ce qu'est le hachage ?Le hachage, vulgairement expliqué est la fonction de transformer une source de données et de le présenter sous un autre format le  exclusivement unique au plus possible.Résumé en _peu_ de caractères alphabétiques et numériques une valeur d'information qui est beaucoup plus grande en information fait partie du domaine de la cryptographie. Résumer la vie d'un tumultueux acteur né dans les années 1930s et mort dans les années 2000s (i.e. donc environs 80 années d'information) en plusieurs bouquins biographique par différents écrivains et qui se lit en quelques heures, est une forme de hashing de la vie, ou plutôt l'information, d'un être humain.Le bouqin est un résumé très minime de sa vie versus le nombre de paroles et de pensées (des données en mots compris et conscientisés) qui ont dû passer à travers l'esprit de cet être et qui en fit l'esprit de son succès du mi-20ième siècle.Un Hashing est essentiellement la même chose en données numériques. Il est fait d'une plus petite quantité d'informations qu'une conscience, mais en degrés d'informations scriptés, i.e. l'histoire de l'humanité, celle des données informatiques sont de très grandes quantitées de données (comme un ou plusieurs livres ou plusieurs appareils IoTs) et se limitent à la base à nos données numériques humaines, nécessitant malgré tout beaucoup de puissance CPU et GPU pour les traiter. Réduire une structure de données en une suite de chiffres et de lettres finie tout en formant un identifiant unique est un des champs d'études en cryptographie et une des applications de la cryptographie en informatique.---**_"A hash is a function that converts one value to another. Hashing data is a common practice in computer science and is used for several different purposes. Examples include cryptography, compression, checksum generation, and data indexing. Hashing is a natural fit for cryptography because it masks the original data with another value."_** (via [https://techterms.com/definition/hash](https://techterms.com/definition/hash) )<jupyter_code>import hashlib<jupyter_output><empty_output><jupyter_text>Exemple de Hashing en PythonAvec une chaîne de caractères comme __"Bonjour, mon nom est Michel!"__ on peut arriver à définir un identifiant unique composé de valeurs définies et produites avec une fonction d'encryption comme celle du sha256() utilisé en programmation informatique.<jupyter_code>phrase = "Bonjour, mon nom est Michel!"
phrase_encodee = phrase.encode('utf-8')
hash = hashlib.sha256(phrase_encodee).hexdigest()
print(hash)<jupyter_output>2a90c4a3da7bc6e3c70d2e8ea896ea4a4bd54a7a3fb2ef43e8b982eb6bc80798<jupyter_text>Résultant le Hash ci-dessus.Si l'on change tout caractère, aussi minimal qu'un seul ou plusieurs, le Hash change.Par exemple, pour "Hasher" maintenant : __"Bonsoir, mon nom est Mich3l!"__; on obtient une valeur différente :<jupyter_code>phrase = "Bonsoir, mon nom est Mich3l!"
phrase_encodee = phrase.encode('utf-8')
hash = hashlib.sha256(phrase_encodee).hexdigest()
print(hash)<jupyter_output>f8633ea4dc33e809acf877777ad6208e47d576494c24141c3680641d2f2fcd60<jupyter_text>Le résultat sortant en est différent.  La difficulté de trouver l'information encryptée, i.e. décrypter un Hash pour définir l'information originale  Les degrées de difficultés de trouver un Hash parmi tant d'autres, d'un nonce parmi tant d'autres : L'essentiel du PoW<jupyter_code>#!/usr/bin/env python
# example of proof-of-work algorithm
# taken from the book Mastering Bitcoin, 2nd Edition
# by <NAME>
# from O'Reilly Media Inc.

import hashlib
import time

try:
    long        # Python 2
    xrange
except NameError:
    long = int  # Python 3
    xrange = range

max_nonce = 2 ** 32  # 4 billion

# ###
# fonction qui défini les opérations pour le proof-of-work
# ###
def proof_of_work(header, difficulty_bits):
    # calculate the difficulty target
    target = 2 ** (256 - difficulty_bits)

    for nonce in xrange(max_nonce):
        hash_result = hashlib.sha256(str(header).encode('utf-8') + str(nonce).encode('utf-8')).hexdigest()

        # check if this is a valid result, below the target
        if long(hash_result, 16) < target:
            print("Success with nonce %d" % nonce)
            print("Hash is %s" % hash_result)
            return (hash_result, nonce)

    print("Failed after %d (max_nonce) tries" % nonce)
    return nonce

# ###
# début d'opération de ce script 
# ###
if __name__ == '__main__':
    nonce = 0
    hash_result = ''

    # difficulty from 0 to 31 bits
    for difficulty_bits in xrange(32):
        difficulty = 2 ** difficulty_bits
        print("--------------------------------------------------------------")
        print("Difficulty: %ld (%d bits)" % (difficulty, difficulty_bits))
        print("Starting search...")

        # checkpoint the current time
        start_time = time.time()

        # make a new block which includes the hash from the previous block
        # we fake a block of transactions - just a string
        new_block = 'test block with transactions' + hash_result

        # find a valid nonce for the new block
        (hash_result, nonce) = proof_of_work(new_block, difficulty_bits)

        # checkpoint how long it took to find a result
        end_time = time.time()

        elapsed_time = end_time - start_time
        print("Elapsed Time: %.4f seconds" % elapsed_time)

        if elapsed_time > 0:

            # estimate the hashes per second
            hash_power = float(long(nonce) / elapsed_time)
            print("Hashing Power: %ld hashes per second" % hash_power)<jupyter_output>--------------------------------------------------------------
Difficulty: 1 (0 bits)
Starting search...
Success with nonce 0
Hash is ff8253ed10b5f719d52a709a66af8cd5e2054f702e675af4ca0cae70f0988634
Elapsed Time: 0.0000 seconds
Hashing Power: 0 hashes per second
--------------------------------------------------------------
Difficulty: 2 (1 bits)
Starting search...
Success with nonce 0
Hash is 22c608547e239faf5c353e7ebd204042760b93891d1d0be9ab488d36c73c077b
Elapsed Time: 0.0000 seconds
Hashing Power: 0 hashes per second
--------------------------------------------------------------
Difficulty: 4 (2 bits)
Starting search...
Success with nonce 2
Hash is 0635f41cdb98c6e73516f84fc88da19a13a3bac6298dbfc0df5170bac93ba4dd
Elapsed Time: 0.0000 seconds
Hashing Power: 57065 hashes per second
--------------------------------------------------------------
Difficulty: 8 (3 bits)
Starting search...
Success with nonce 9
Hash is 1c1c105e65b47142f028a8f93ddf3dabb9260491bc64474738133ce5256cb3c1
Elapsed [...]
{'fraction_non_alphanumeric': 0.0899100899100899, 'fraction_numerical': 0.037296037296037296, 'mean_word_length': 3.7123430962343096, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 16, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '20861', 'license': 'MIT', 'n_tokens_mistral': 2937, 'n_tokens_neox': 2744, 'n_words': 1106, 'path': 'exemple_PdT.ipynb', 'repo_name': 'SerafDosSantos/MesBlocNotes', 'size': '9026'}