Article haut niveau sur la compréhension des fameuses chaines de blocs qui font couler beaucoup d’encre depuis la hype du saint bitcoin.
Je suis loin d’être la personne la plus pointue sur ce sujet qui est vaste et complexe.
Du coup, on va créer ensemble une petite blockchain en python qui n’aura aucun algo de validation.
Restons simple.

Alors késséssé ?

Comme sa traduction le dit si bien, une blockchain n’est ni plus ni moins qu’une chaine de blocs.
Chaque bloc a sa propre identité qui est unique au sein de la chaine, et pour que chacun des blocs
sachent où il est dans la chaine il utilise l’identité du bloc précédent pour se mettre à la suite.

Photo chaine-de-blocs

Le premier bloc, aussi appelé genesis, est le seul qui n’a pas de parent (identité du bloc précédent).
Tous les autres vont réussir à trouver leur place grâce à l’identité de leur parent.

Si vous utilisez python avec alembic par exemple, qui est un outil de migration qu’on utilise avec SQL Alchemy,
vous retrouverez ce principe.
Chaque révision générée porte le nom d’un commit ainsi que le commit de la révision précédente. Ce qui permettra à Alembic d’éxécuter les révisions dans le bon ordre.
Idem, si vous utilisez Git, ce principe de chaine liée à une identité (commit) doit vous parler.

Une blockchain “classique” n’est ni plus ni moins que ça.
Après s’ajoutera tout l’aspect de décentralisation et de vérification.

Créons une blockchain en python.

Un block, sera un objet. Cet objet comportera des données, un index, nos hash et un timestamp.

class Block:
    def __init__(self, data, index, timestamp, prevhash=""):
        self.data = data
        self.index = index
        self.prevhash = prevhash
        self.timestamp = timestamp
        self.hash = self.hashblock()

La fonction hashblock() correspond à l’identité du bloc. On va utiliser du classique, et regrouper l’index, timestamp, data et le hash du bloc précédent pour le passer dans une fonction de hachage du module hashlib.

def hashblock(self):
    encryption_object = hashlib.sha256()
    data = str(self.index) + str(self.timestamp) + str(self.data) + str(self.prevhash)
    encryption_object.update(data.encode("utf-8"))
    
    return encryption_object.hexdigest()

Créons une methode statique qui permettra de créer notre tout premier bloc, el famoso genesis !

@staticmethod
def genesis():
    return Block(
        data="genesis block",
        index=0,
        timestamp=datetime.datetime.now(),
    )

On a notre premier bloc, maintenant dernière étape avec la création d’un nouveau.

@staticmethod
def create(previous_block):
    index = previous_block.index + 1
    timestamp = datetime.datetime.now()
    previous_hash = previous_block.hash
    data = f"Transaction {str(index)}"

    return Block(
        data=data,
        index=index,
        prevhash=previous_hash,
        timestamp=timestamp,
    )

La classe Block est cohérente, on peut maintenant essayer d’en créer plusieurs et faire une belle chaine.

def print_info(block):
    print("---------------")
    print(f"Index: {block.index}")
    print(f"Timestamp: {block.timestamp}")
    print(f"Previous hash: {block.prevhash}")
    print(f"Hash: {block.hash}")

def main():
    blockchain = [Block.genesis()]
    previous_block = blockchain[0]
    print_info(block=previous_block)

    for i in range(0, 5):
        block = Block.create(previous_block=previous_block)
        blockchain.append(block)
        print_info(block=block)

        previous_block=block

Et voilà on vient de créer une chaine de blocs dans son plus simple appareil.

Photo result-blocs