Implémentation d'un système blockchain simplifié en Python

Srtucture de base des blocs et chaîne

Block.py

import hashlib
from datetime import datetime

class Bloc:
    def __init__(self, transactions, hash_precedent):
        self.hash_precedent = hash_precedent
        self.transactions = transactions
        self.horodatage = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.nonce = None
        self.hash_bloc = None

    def __repr__(self):
        return f"Transactions: {self.transactions}\nHash: {self.hash_bloc}"

class PreuveTravail:
    def __init__(self, bloc, mineur, difficulte=5):
        self.bloc = bloc
        self.mineur = mineur
        self.difficulte = difficulte
        self.recompense = 1

    def miner(self):
        prefixe = '0' * self.difficulte
        i = 0
        
        transaction_recompense = Transaction(
            emetteur="",
            destinataire=self.mineur.adresse,
            montant=self.recompense
        )
        self.bloc.transactions.append(transaction_recompense)
        
        while True:
            contenu = f"{self.bloc.hash_precedent}{self.bloc.transactions}{self.bloc.horodatage}{i}"
            hash_candidat = hashlib.sha256(contenu.encode()).hexdigest()
            
            if hash_candidat.startswith(prefixe):
                self.bloc.nonce = i
                self.bloc.hash_bloc = hash_candidat
                return self.bloc
            i += 1

    def valider(self):
        contenu = f"{self.bloc.hash_precedent}{self.bloc.transactions}{self.bloc.horodatage}{self.bloc.nonce}"
        hash_verifie = hashlib.sha256(contenu.encode()).hexdigest()
        return hash_verifie.startswith('0' * self.difficulte)

Gestion des transactions et portefeuillse

Transaction.py

import json

class Transaction:
    def __init__(self, emetteur, destinataire, montant):
        self.emetteur = emetteur
        self.destinataire = destinataire
        self.montant = montant
        self.signature = None
        self.cle_publique = None

    def ajouter_signature(self, signature, cle_publique):
        self.signature = signature
        self.cle_publique = cle_publique

    def __repr__(self):
        if self.emetteur:
            return f"{self.emetteur} → {self.destinataire} ({self.montant})"
        return f"Récompense minage: {self.destinataire} ({self.montant})"

Portefeuille.py

from ecdsa import SigningKey, SECP256k1
import hashlib
import base64

class Portefeuille:
    def __init__(self):
        self.cle_privee = SigningKey.generate(curve=SECP256k1)
        self.cle_publique = self.cle_privee.verifying_key
    
    @property
    def adresse(self):
        hash_pub = hashlib.sha256(self.cle_publique.to_pem()).digest()
        return base64.b64encode(hash_pub).decode()
    
    def signer(self, message):
        return self.cle_privee.sign(message.encode())

def verifier_signature(cle_publique, message, signature):
        verificateur = VerifyingKey.from_pem(cle_publique)
        return verificateur.verify(signature, message.encode())

Structure et opérations blockchain

Blockchain.py

class Blockchain:
    def __init__(self):
        self.chain = []
    
    def ajouter_bloc(self, bloc):
        self.chain.append(bloc)
    
    def solde(self, adresse):
        total = 0
        for bloc in self.chain:
            for tx in bloc.transactions:
                if tx.emetteur == adresse:
                    total -= tx.montant
                if tx.destinataire == adresse:
                    total += tx.montant
        return total

def creer_genese(createur):
    blockchain = Blockchain()
    bloc_genese = Bloc([], "")
    pow = PreuveTravail(bloc_genese, createur)
    bloc_miné = pow.miner()
    blockchain.ajouter_bloc(bloc_miné)
    return blockchain

Exemple d'utilisation

# Initialisation
portefeuille_A = Portefeuille()
portefeuille_B = Portefeuille()

blockchain = creer_genese(portefeuille_A)

# Création transaction
tx = Transaction(portefeuille_A.adresse, portefeuille_B.adresse, 0.8)
tx.ajouter_signature(
    portefeuille_A.signer(str(tx)),
    portefeuille_A.cle_publique.to_pem()
)

# Vérification et minage
if verifier_signature(tx.cle_publique, str(tx), tx.signature):
    nouveau_bloc = Bloc([tx], blockchain.chain[-1].hash_bloc)
    pow = PreuveTravail(nouveau_bloc, portefeuille_B)
    bloc_valide = pow.miner()
    blockchain.ajouter_bloc(bloc_valide)

print(f"Solde A: {blockchain.solde(portefeuille_A.adresse)}")
print(f"Solde B: {blockchain.solde(portefeuille_B.adresse)}")

Étiquettes: Blockchain Python preuve de travail cryptomonnaie ECDSA

Publié le 17 juin à 01h26