Cum se creează un Blockchain cu Python?

Înțelegerea și Crearea unui Blockchain în Python

Ați auzit vreodată că Bitcoin funcționează pe baza tehnologiei Blockchain? Astăzi, vom crea un blockchain folosind Python, de la început.

Ce reprezintă Blockchain-ul?

În anul 2008, o lucrare intitulată „Bitcoin” a fost publicată de un individ sau un grup anonim, cunoscut sub numele de Satoshi Nakamoto. Această lucrare a introdus Bitcoin ca un sistem de numerar electronic de tip peer-to-peer, care permitea tranzacții fără intermediari, cum ar fi băncile. Ceea ce nu știu mulți este că în aceeași lucrare, Satoshi a descris și o metodă distribuită de stocare a informațiilor, cunoscută astăzi sub numele de Blockchain.

Esenta tehnologiei Blockchain

Blockchain-ul, într-o definiție simplificată, este un registru digital partajat și imuabil. Acesta stochează tranzacțiile printr-o rețea descentralizată de computere.

Structura unui Blockchain poate fi înțeleasă prin două concepte:

  • Bloc: Un spațiu dedicat stocării tranzacțiilor.
  • Lanț: O serie de înregistrări interconectate.

Astfel, un Blockchain este un lanț de blocuri legate între ele, unde fiecare bloc memorează o tranzacție efectuată, împreună cu anumite caracteristici.

Fiecare bloc este construit peste blocul precedent, formând un lanț permanent. Astfel, fiecare bloc este dependent de cel care îl precede. Această structură oferă un sistem robust și imuabil, în care oricine cu permisiunile necesare poate verifica integritatea datelor.

Blockchain-ul aduce un set important de avantaje:

  • Istoric imuabil
  • Informații stocate permanent
  • Date stocate fără erori

În prezent, numeroase sisteme se bazează pe Blockchain, inclusiv criptomonede, transferuri de active (NFT-uri) și, probabil, votul electronic în viitorul apropiat.

Un blockchain creat în Python nu este neapărat un program complex, cu mii de linii de cod. La bază, este o simplă listă de tranzacții interconectate.

Aceasta a fost o introducere sumară. Dacă sunteți interesat de o înțelegere mai profundă, vă recomandăm un tutorial complet despre Blockchain pentru începători, disponibil aici.

Acum, să trecem la construirea propriului nostru blockchain, folosind Python.

Cum construim un Blockchain cu Python

Înainte de a începe, vom stabili obiectivele acestui tutorial:

  • Vom crea un sistem Blockchain simplu, folosind Python.
  • Vom utiliza blockchain-ul cu tranzacții definite în prealabil, sub formă de șiruri de caractere.
  • Vom verifica imuabilitatea blockchain-ului nostru.

Nu vom folosi JSON, ci liste Python, pentru a simplifica procesul și a ne concentra pe principiile de bază ale unui Blockchain.

Iată ce veți avea nevoie pentru a continua:

Crearea Clasei Block

Deschideți editorul de cod preferat și creați un fișier denumit „main.py”. Acesta va fi fișierul cu care vom lucra.

Apoi, importați modulul hashlib, care vă permite să generați mesaje criptate unidirecționale. Tehnici de criptare precum hashing-ul sunt esențiale pentru a crea tranzacții sigure într-un Blockchain.

O funcție hash este un algoritm care primește anumite date (de obicei, un șir codificat) și produce un identificator unic, numit „digest” sau „semnătură”. Caracteristica definitorie a unei funcții hash este că o mică modificare în datele de intrare va genera un identificator complet diferit ca ieșire. Vom vedea asta în acțiune mai târziu.

Pentru moment, importați modulul hashlib inclus:

# main.py file
"""
Un Blockchain simplu în Python
"""

import hashlib

Acest modul oferă majoritatea algoritmilor de hashing de care veți avea nevoie. Vom folosi în special funcția `hashlib.sha256()`.

Acum, să creăm clasa GeekCoinBlock, numele original al blockchain-ului nostru.

class GeekCoinBlock:
    
    def __init__(self, previous_block_hash, transaction_list):

        self.previous_block_hash = previous_block_hash
        self.transaction_list = transaction_list

        self.block_data = f"{' - '.join(transaction_list)} - {previous_block_hash}"
        self.block_hash = hashlib.sha256(self.block_data.encode()).hexdigest()

Acest cod poate părea complicat, așa că îl vom explica în următoarea secțiune.

Explicarea clasei GeekCoinBlock

Începem prin a defini o clasă numită GeekCoinBlock, un model pentru obiecte care vor avea anumite proprietăți (atribute) și acțiuni (metode).

Apoi, definim metoda `__init__` (cunoscută și ca constructor), care este executată de fiecare dată când este creat un obiect GeekCoinBlock.

Această metodă are trei parametri:

  • `self` (instanța fiecărui obiect)
  • `previous_block_hash` (o referință către blocul anterior)
  • `transaction_list` (o listă cu tranzacțiile care au avut loc în blocul curent).

Stocăm hash-ul anterior și lista de tranzacții. Creăm o variabilă de instanță, `block_data`, ca șir. Deși în criptomonede reale acest tip de date este stocat ca un alt hash, pentru simplitate vom stoca fiecare set de date ca un șir.

În cele din urmă, creăm `block_hash`, pe care alte blocuri îl vor folosi pentru a continua lanțul. Aici intervine utilitatea modulului `hashlib`. În loc să creăm o funcție hash personalizată, folosim funcția predefinită `sha256` pentru a face blocurile imuabile.

Această funcție primește ca parametri șiruri (sau octeți) codificați. De aceea, folosim metoda `block_data.encode()`. După aceea, apelăm `hexdigest()` pentru a returna datele codificate în format hexazecimal.

Înțeleg că poate fi mult de asimilat, așa că vom folosi modulul `hashlib` în consolă Python.

In [1]: import hashlib

In [2]: message = "Python is great"

In [3]: h1 = hashlib.sha256(message.encode())

In [4]: h1
Out[4]: <sha256 ... object @ 0x7efcd55bfbf0>

In [5]: h1.hexdigest()
Out[5]: 'a40cf9cca ... 42ab97'

In [6]: h2 = hashlib.sha256(b"Python is not great")

In [7]: h2
Out[7]: <sha256 ... object @ 0x7efcd55bfc90>

In [8]: h2.hexdigest()
Out[8]: 'fefe510a6a ... 97e010c0ea34'

După cum se poate observa, o mică modificare a intrării, de la „Python este grozav” la „Python nu este grozav”, generează un hash complet diferit. Acest lucru este legat de integritatea unui Blockchain. Dacă se introduce o mică modificare într-un blockchain, hash-ul său se va schimba semnificativ. De aici și expresia „Nu se poate corupe un Blockchain”.

Utilizarea clasei Block

Vom construi o clasă Blockchain completă mai târziu, dar, pentru început, vom folosi clasa Block pentru a crea un lanț de blocuri (Blockchain).

În același fișier, creați câteva tranzacții sub forma unor șiruri simple, stocate în variabile, de exemplu:

class GeekCoinBlock:
    ...

t1 = "Noah trimite 5 GC lui Mark"
t2 = "Mark trimite 2.3 GC lui James"
t3 = "James trimite 4.2 GC lui Alisson"
t4 = "Alisson trimite 1.1 GC lui Noah"

Desigur, GC reprezintă GeekCoin.

Acum, construiți primul bloc al blockchain-ului nostru, folosind clasa GeekCoinBlock și afișați atributele sale. Rețineți că parametrul `previous_hash` al blocului geneză (primul bloc, care precede toate celelalte blocuri) va fi întotdeauna un șir arbitrar sau un hash. În acest caz, va fi „firstblock”.

block1 = GeekCoinBlock('firstblock', [t1, t2])

print(f"Date bloc 1: {block1.block_data}")
print(f"Hash bloc 1: {block1.block_hash}")

Apoi, repetăm procesul cu al doilea bloc, dar folosind hash-ul primului bloc ca argument `previous_hash`.

block2 = GeekCoinBlock(block1.block_hash, [t3, t4])

print(f"Date bloc 2: {block2.block_data}")
print(f"Hash bloc 2: {block2.block_hash}")

Să rulăm codul și să analizăm rezultatele. Introduceți următoarea comandă în terminalul dvs.:

❯ python main.py
Date bloc 1: Noah trimite 5 GC lui Mark - Mark trimite 2.3 GC lui James - firstblock
Hash bloc 1: 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Date bloc 2: James trimite 4.2 GC lui Alisson - Alisson trimite 1.1 GC lui Noah - 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Hash bloc 2: 448c4306caf7f6937b0307f92f27fbea3bb73b3470363dee5026a1209dadcfa8

Momentan vedem doar text și hash-uri de aproximativ 64 de caractere, dar acest lucru ilustrează mecanismul de bază al unui Blockchain.

Începem cu un bloc geneză, fundația tuturor celorlalte blocuri.

Oricine poate verifica integritatea lanțului, ceea ce face ca Blockchain-ul să fie un sistem sigur. De exemplu, dacă modificăm puțin conținutul unei tranzacții, să spunem:

t2 = "Mark trimite 2.3 GC lui James" -> t2 = "Mark trimite 3.2 GC lui James"

Observăm o schimbare majoră a hash-urilor blocurilor:

Date bloc 1: Noah trimite 5 GC lui Mark - Mark trimite 3.2 GC lui James - firstblock
Hash bloc 1: 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Date bloc 2: James trimite 4.2 GC lui Alisson - Alisson trimite 1.1 GC lui Noah - 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Hash bloc 2: 569b977306ce88b53e001dca7ba00c03a51c60d6df4650e7657dcd136f2da0ac

Puteți consulta proiectul curent în acest Repoziție GitHub.

Codificarea unui Blockchain

Nu este ideal să ne bazăm integritatea sistemului pe variabile codificate manual, așa că vom folosi o altă abordare.

Avem blocurile. Acum este timpul să construim o clasă care să le combine într-un Blockchain.

Începem prin a șterge tranzacțiile și obiectele bloc anterioare, apoi vom folosi codul de mai jos.

# main.py

class Blockchain:
    def __init__(self):
        self.chain = []
        self.generate_genesis_block()

    def generate_genesis_block(self):
        self.chain.append(GeekCoinBlock("0", ['Bloc Geneză']))
    
    def create_block_from_transaction(self, transaction_list):
        previous_block_hash = self.last_block.block_hash
        self.chain.append(GeekCoinBlock(previous_block_hash, transaction_list))

    def display_chain(self):
        for i in range(len(self.chain)):
            print(f"Date {i + 1}: {self.chain[i].block_data}")
            print(f"Hash {i + 1}: {self.chain[i].block_hash}n")

    @property
    def last_block(self):
        return self.chain[-1]

Acesta este un alt bloc mare de cod. Să explicăm fiecare parte:

  • `self.chain` – Lista unde sunt înregistrate toate blocurile. Fiecare bloc poate fi accesat prin intermediul indexurilor listei.
  • `generate_genesis_block` – Adaugă blocul geneză, sau primul bloc, la lanț. Hash-ul anterior al blocului este „0”, iar lista de tranzacții este simplu „Blocul Geneză”.
  • `create_block_from_transaction` – Permite adăugarea blocurilor la lanț folosind doar o listă de tranzacții. Ar fi foarte greu să creăm un bloc manual de fiecare dată când dorim să înregistrăm o tranzacție.
  • `display_chain` – Afișează lanțul de blocuri folosind o buclă for.
  • `last_block` – O proprietate care permite accesul la ultimul element din lanț. Aceasta a fost folosită în metoda `create_block_from_transaction`.

Să testăm acum acest Blockchain.

# main.py

import hashlib

class GeekCoinBlock:
    ...


class Blockchain:
    ...

t1 = "George trimite 3.1 GC lui Joe"
t2 = "Joe trimite 2.5 GC lui Adam"
t3 = "Adam trimite 1.2 GC lui Bob"
t4 = "Bob trimite 0.5 GC lui Charlie"
t5 = "Charlie trimite 0.2 GC lui David"
t6 = "David trimite 0.1 GC lui Eric"

myblockchain = Blockchain()

myblockchain.create_block_from_transaction([t1, t2])
myblockchain.create_block_from_transaction([t3, t4])
myblockchain.create_block_from_transaction([t5, t6])

myblockchain.display_chain()

Acum, rulați fișierul main.py.

Date 1: Bloc Geneză - 0
Hash 1: 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e

Date 2: George trimite 3.1 GC lui Joe - Joe trimite 2.5 GC lui Adam - 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e
Hash 2: 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5

Date 3: Adam trimite 1.2 GC lui Bob - Bob trimite 0.5 GC lui Charlie - 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5
Hash 3: 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589

Date 4: Charlie trimite 0.2 GC lui David - David trimite 0.1 GC lui Eric - 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589
Hash 4: 869df2f03c9860767d35b30a46233fbeea89a3000ae5019d1491e3829d1ab929

Felicitări! Tocmai ați creat un blockchain simplu în Python, de la zero.

Acum puteți consolida imuabilitatea Blockchain-ului, folosind metode getter și setter. De asemenea, puteți implementa și alte caracteristici, precum dovada de lucru, mineritul, sau orice alt concept pe care l-am explicat în articolul introductiv despre mineritul Bitcoin.

Concluzii

Blockchain-ul este tehnologia de bază pentru Bitcoin, Etherium și toate celelalte criptomonede. În acest articol, ați învățat cum să creați un Blockchain cu Python folosind algoritmi de hash precum sha256, clase și obiecte.

Provocarea este să creați un sistem de minerit, și de ce nu, să-l implementați cu un API REST, folosind framework-uri ca Django sau Flask.

Mulți oameni câștigă sume mari de bani din criptomonede. Imaginați-vă ce ați putea realiza dacă ați crea una proprie! 🤑

Continuați să programați! 👨‍💻