Πώς να δημιουργήσετε ένα Blockchain με την Python;

Γνωρίζατε ότι το Bitcoin είναι χτισμένο πάνω από το Blockchain; Σήμερα θα δημιουργήσουμε ένα Blockchain με την Python από την αρχή.

Τι είναι το Blockchain;

Το 2008 το χαρτί Bitcoin δημοσιεύτηκε από ένα άγνωστο άτομο ή ομάδα με το όνομα Satoshi Nakamoto. Το Bitcoin εμφανίστηκε ως μια peer-to-peer έκδοση ηλεκτρονικών μετρητών που επέτρεπε συναλλαγές χωρίς να περάσουν από κεντρικά ιδρύματα (τράπεζες). Οι περισσότεροι άνθρωποι δεν γνωρίζουν ότι στο ίδιο έγγραφο, ο Satoshi όρισε έναν κατανεμημένο τρόπο αποθήκευσης πληροφοριών, που σήμερα είναι γνωστός ως Blockchain.

Τεχνολογία Blockchain

Για να το θέσω απλά, το Blockchain είναι ένα κοινόχρηστο, αμετάβλητο ψηφιακό βιβλίο που αποθηκεύει συναλλαγές μέσω ενός αποκεντρωμένου δικτύου υπολογιστών.

Μπορούμε να χωρίσουμε το Blockchain σε δύο απλούς όρους:

  • Μπλοκ: Ένας χώρος όπου αποθηκεύουμε συναλλαγές
  • Αλυσίδα: Ένα σύνολο συνδεδεμένων εγγραφών

Αυτό ορίζει το Blockchain ως μια αλυσίδα συνδεδεμένων μπλοκ, όπου κάθε μπλοκ αποθηκεύει μια συναλλαγή που πραγματοποιείται με συγκεκριμένες παραμέτρους.

Κάθε μπλοκ είναι χτισμένο πάνω από ένα άλλο μπλοκ, δημιουργώντας μια μη αναστρέψιμη αλυσίδα μπλοκ. Με άλλα λόγια, κάθε μπλοκ εξαρτάται από ένα άλλο. Αυτό μετατρέπεται σε ένα ισχυρό και αμετάβλητο σύστημα στο οποίο οποιοσδήποτε έχει τα σωστά δικαιώματα μπορεί να ελέγξει την ακεραιότητα.

Το Blockchain εισάγει ένα ενδιαφέρον σύνολο χαρακτηριστικών:

  • Ιστορικό αμετάβλητο
  • Πληροφοριακή εμμονή
  • Δεν υπάρχουν σφάλματα με τα αποθηκευμένα δεδομένα

Πολλά συστήματα βασίζονται επί του παρόντος στο Blockchain, όπως τα κρυπτονομίσματα, η μεταφορά περιουσιακών στοιχείων (NFT) και πιθανώς στο εγγύς μέλλον η ψηφοφορία.

Αξίζει να αναφέρουμε ότι ένα Python Blockchain δεν πρέπει να είναι ένα σύνθετο πρόγραμμα με χιλιάδες γραμμές κώδικα. Στον πυρήνα του, θα ήταν μια λίστα συναλλαγών που συνδέονται μεταξύ τους.

Φυσικά, αυτή ήταν μια σύντομη εξήγηση, αλλά αν θέλετε έναν πλήρη οδηγό, δημιουργήσαμε ένα πλήρες σεμινάριο για το Blockchain για αρχάριους. Φροντίστε να το ελέγξετε.

Χωρίς περαιτέρω καθυστέρηση, ας δημιουργήσουμε ένα απλό Blockchain με την Python.

Δημιουργία Blockchain με Python

Πριν ξεκινήσουμε, ας ορίσουμε τι πρόκειται να κάνουμε σε αυτό το σεμινάριο:

  • Δημιουργήστε απλό σύστημα Blockchain γραμμένο σε Python
  • Χρησιμοποιήστε το Blockchain μας με προκαθορισμένες συναλλαγές που αντιπροσωπεύονται ως συμβολοσειρές
  • Δοκιμάστε το αμετάβλητο του Blockchain μας

Δεν πρόκειται να χρησιμοποιήσουμε JSON αλλά λίστες Python. Αυτό θα μας επιτρέψει να απλοποιήσουμε τη διαδικασία και να επικεντρωθούμε στην εφαρμογή των βασικών εννοιών ενός Blockchain.

Τι θα χρειαστείτε για να ακολουθήσετε αυτό το σεμινάριο:

Δημιουργία της κλάσης Block

Ανοίξτε τον αγαπημένο σας επεξεργαστή κώδικα και δημιουργήστε ένα αρχείο main.py. Αυτό θα είναι το αρχείο με το οποίο θα εργαστούμε.

  Πού να βρείτε δωρεάν διαδικτυακά μαθήματα για να μάθετε κάτι νέο;

Τώρα, εισαγωγή hashlib, μια λειτουργική μονάδα που μας επιτρέπει να δημιουργήσουμε μονόδρομα κρυπτογραφημένα μηνύματα. Οι τεχνικές κρυπτογραφίας, όπως το κατακερματισμό, κάνουν το Blockchain να δημιουργεί ασφαλείς συναλλαγές.

Μια συνάρτηση κατακερματισμού είναι ένας αλγόριθμος που λαμβάνει ορισμένα δεδομένα (συνήθως μια κωδικοποιημένη συμβολοσειρά) και επιστρέφει ένα μοναδικό αναγνωριστικό, που συχνά ονομάζεται “digest” ή “signature”. Αυτό το τελευταίο μέρος είναι ζωτικής σημασίας. με μια συνάρτηση κατακερματισμού, μια μικρή διαφορά στην είσοδο παράγει ένα ριζικά διαφορετικό αναγνωριστικό ως έξοδο. Θα το δούμε στην πράξη αργότερα.

Προς το παρόν, απλώς εισαγάγετε την ενσωματωμένη ενότητα hashlib:

# main.py file
"""
A simple Blockchain in Python
"""

import hashlib

Αυτή η ενότητα περιλαμβάνει τους περισσότερους από τους αλγόριθμους κατακερματισμού που θα χρειαστείτε. Απλώς έχετε κατά νου ότι θα χρησιμοποιήσουμε τη συνάρτηση hashlib.sha256().

Τώρα, ας μπούμε στο GeekCoinBlock, το εντελώς αρχικό μας όνομα blockchain.

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()

Ξέρω ότι αυτό μπορεί να οδηγήσει σε ένα βαρύ κομμάτι κώδικα. Ας αναλύσουμε κάθε μέρος στην επόμενη ενότητα.

Επεξήγηση GeekCoinBlock

Αρχικά, δημιουργούμε μια κλάση με το όνομα GeekCoinBlock, ένα περιτύλιγμα για αντικείμενα που θα έχουν ορισμένα χαρακτηριστικά (χαρακτηριστικά) και συμπεριφορές (μέθοδοι).

Στη συνέχεια ορίζουμε τη μέθοδο __init__ (ονομάζεται επίσης κατασκευαστής), η οποία καλείται κάθε φορά που δημιουργείται ένα αντικείμενο GeekCoinBlock.

Αυτή η μέθοδος έχει τρεις παραμέτρους:

  • εαυτός (το παράδειγμα κάθε αντικειμένου)
  • previous_block_hash (αναφορά στο προηγούμενο μπλοκ)
  • transaction_list (μια λίστα συναλλαγών που έγιναν στο τρέχον μπλοκ).

Αποθηκεύουμε την προηγούμενη λίστα κατακερματισμού και συναλλαγών και δημιουργούμε μια στιγμιαία μεταβλητή block_data ως συμβολοσειρά. Αυτό δεν συμβαίνει με τα πραγματικά κρυπτονομίσματα, στα οποία αποθηκεύουμε αυτού του είδους τα δεδομένα ως άλλο κατακερματισμό, αλλά για λόγους απλότητας, θα αποθηκεύουμε κάθε μπλοκ δεδομένων ως συμβολοσειρά.

Τέλος, δημιουργούμε το block_hash, το οποίο άλλα μπλοκ θα χρησιμοποιήσουν για να συνεχίσουν την αλυσίδα. Εδώ είναι χρήσιμο το hashlib. Αντί να δημιουργήσουμε μια προσαρμοσμένη συνάρτηση κατακερματισμού, μπορούμε να χρησιμοποιήσουμε το προκατασκευασμένο sha256 για να δημιουργήσουμε αμετάβλητα μπλοκ.

Αυτή η συνάρτηση λαμβάνει κωδικοποιημένες συμβολοσειρές (ή byte) ως παραμέτρους. Γι’ αυτό χρησιμοποιούμε τη μέθοδο block_data.encode(). Μετά από αυτό, καλούμε την hexdigest() για να επιστρέψει τα κωδικοποιημένα δεδομένα σε δεκαεξαδική μορφή.

Ξέρω ότι όλα αυτά μπορεί να είναι συντριπτικά, οπότε ας παίξουμε με το hashlib σε ένα κέλυφος 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'

Όπως μπορείτε να δείτε, μια μικρή αλλαγή στην είσοδο όπως “Η Python είναι εξαιρετική” σε “Η Python δεν είναι υπέροχη” μπορεί να δημιουργήσει έναν εντελώς διαφορετικό κατακερματισμό. Όλα αυτά έχουν να κάνουν με την ακεραιότητα του Blockchain. Εάν εισάγετε κάποια μικρή αλλαγή σε ένα blockchain, ο κατακερματισμός του θα αλλάξει δραματικά. Αυτός είναι ο λόγος που ισχύει το ρητό «Δεν μπορείς να διαφθείρεις ένα Blockchain».

  30 Χρόνια «Ναρκοκαθαριστής» (Σουντόκου με Εκρήξεις)

Χρήση της τάξης μπλοκ μας

Θα δημιουργήσουμε μια ολόκληρη κατηγορία Blockchain αργότερα, αλλά προς το παρόν, ας χρησιμοποιήσουμε την τάξη Block για να δημιουργήσουμε μια αλυσίδα μπλοκ (Blockchain).

Στο ίδιο αρχείο, δημιουργήστε μερικές συναλλαγές που αποτελούνται από απλές συμβολοσειρές που είναι αποθηκευμένες σε μεταβλητές, για παράδειγμα:

class GeekCoinBlock:
    ...

t1 = "Noah sends 5 GC to Mark"
t2 = "Mark sends 2.3 GC to James"
t3 = "James sends 4.2 GC to Alisson"
t4 = "Alisson sends 1.1 GC to Noah"

Φυσικά, το GC αναφέρεται στο GeekCoin

Τώρα, δημιουργήστε το πρώτο μπλοκ του Blockchain μας χρησιμοποιώντας την κλάση GeekCoinBlock και εκτυπώστε τα χαρακτηριστικά του. Λάβετε υπόψη ότι η παράμετρος previous_hash του μπλοκ γένεσης (το πρώτο μπλοκ που προηγείται των άλλων μπλοκ) θα είναι πάντα κάποια αυθαίρετη συμβολοσειρά ή κατακερματισμός, σε αυτήν την περίπτωση, “firstblock”.

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

print(f"Block 1 data: {block1.block_data}")
print(f"Block 1 hash: {block1.block_hash}")

Στη συνέχεια, κάνουμε το ίδιο με το δεύτερο μπλοκ, αλλά περνώντας τον πρώτο κατακερματισμό μπλοκ ως όρισμα previous_hash.

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

print(f"Block 2 data: {block2.block_data}")
print(f"Block 2 hash: {block2.block_hash}")

Ας τρέξουμε και ας αναλύσουμε την έξοδο που παίρνουμε από αυτό το κομμάτι κώδικα. Για άλλη μια φορά, πληκτρολογήστε στο τερματικό σας:

❯ python main.py
Block 1 data: Noah sends 5 GC to Mark - Mark sends 2.3 GC to James - firstblock
Block 1 hash: 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 hash: 448c4306caf7f6937b0307f92f27fbea3bb73b3470363dee5026a1209dadcfa8

Προς το παρόν, βλέπετε μόνο κείμενο και κατακερματισμούς 64 χαρακτήρων, αλλά αυτό επαναλαμβάνει λίγο πολύ τον μηχανισμό ενός Blockchain.

Ξεκινάτε με ένα μπλοκ γένεσης, τη βάση όλων των άλλων μπλοκ.

Οποιοσδήποτε μπορεί να επικυρώσει την ακεραιότητα της αλυσίδας και γι’ αυτό ένα Blockchain είναι ένα τόσο ασφαλές σύστημα. Για παράδειγμα, αν τροποποιήσουμε ελαφρώς το περιεχόμενο μιας συναλλαγής, ας πούμε:

t2 = "Mark sends 2.3 GC to James" -> t2 = "Mark sends 3.2 GC to James" 

Βλέπουμε μια δραματική αλλαγή στον κατακερματισμό των μπλοκ.

Block 1 data: Noah sends 5 GC to Mark - Mark sends 3.2 GC to James - firstblock
Block 1 hash: 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 hash: 569b977306ce88b53e001dca7ba00c03a51c60d6df4650e7657dcd136f2da0ac

Μπορείτε να δείτε το τρέχον έργο σε αυτό Αποθετήριο GitHub.

Κωδικοποίηση Blockchain

Δεν είναι τόσο έξυπνο να βασίζουμε την ακεραιότητα του συστήματός μας σε μεταβλητές με το χέρι, οπότε χρειαζόμαστε μια άλλη προσέγγιση.

  Πώς μπορείτε να σταματήσετε το Roblox από την υπερθέρμανση

Έχουμε τα μπλοκ. Ήρθε η ώρα να δημιουργήσετε μια τάξη που να τις ενώνει σε ένα Blockchain.

Ας ξεκινήσουμε διαγράφοντας τις προηγούμενες συναλλαγές μας και τα αντικείμενα αποκλεισμού και, στη συνέχεια, χρησιμοποιώντας τον παρακάτω κώδικα.

# main.py

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

    def generate_genesis_block(self):
        self.chain.append(GeekCoinBlock("0", ['Genesis Block']))
    
    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"Data {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]

Αυτό είναι και πάλι ένα τεράστιο κομμάτι κώδικα. Ας αναλύσουμε κάθε μέρος:

  • self.chain — Η λίστα όπου καταγράφονται όλα τα μπλοκ. Μπορούμε να έχουμε πρόσβαση σε κάθε μπλοκ μέσω ευρετηρίων λίστας.
  • generate_genesis_block — Προσθέστε τη γένεση ή το πρώτο μπλοκ στην αλυσίδα. Ο προηγούμενος κατακερματισμός του μπλοκ είναι “0” και η λίστα των συναλλαγών είναι απλώς “Genesis Block”.
  • create_block_from_transaction — Αυτό μας επιτρέπει να προσαρτούμε μπλοκ στην αλυσίδα μόνο με μια λίστα συναλλαγών. Θα ήταν πολύ ενοχλητικό να δημιουργούμε ένα μπλοκ χειροκίνητα κάθε φορά που θέλουμε να καταγράψουμε μια συναλλαγή
  • display_chain — Εκτυπώνει την αλυσίδα των μπλοκ με έναν βρόχο for
  • last_block — Μια ιδιότητα που μας επιτρέπει να έχουμε πρόσβαση στο τελευταίο στοιχείο της αλυσίδας. Το χρησιμοποιήσαμε στη μέθοδο create_block_from_transaction.

Ας δοκιμάσουμε αυτό το Blockchain.

# main.py

import hashlib

class GeekCoinBlock:
    ...


class Blockchain:
    ...

t1 = "George sends 3.1 GC to Joe"
t2 = "Joe sends 2.5 GC to Adam"
t3 = "Adam sends 1.2 GC to Bob"
t4 = "Bob sends 0.5 GC to Charlie"
t5 = "Charlie sends 0.2 GC to David"
t6 = "David sends 0.1 GC to 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()

Τώρα, εκτελέστε το αρχείο main.py.

Data 1: Genesis Block - 0
Hash 1: 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e

Data 2: George sends 3.1 GC to Joe - Joe sends 2.5 GC to Adam - 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e
Hash 2: 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5

Data 3: Adam sends 1.2 GC to Bob - Bob sends 0.5 GC to Charlie - 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5
Hash 3: 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589

Data 4: Charlie sends 0.2 GC to David - David sends 0.1 GC to Eric - 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589
Hash 4: 869df2f03c9860767d35b30a46233fbeea89a3000ae5019d1491e3829d1ab929

Συγχαρητήρια! 🙌 Μόλις δημιουργήσατε ένα απλό Python Blockchain από την αρχή.

Τώρα μπορείτε να ενισχύσετε την αμετάβλητη αλυσίδα Blockchain χρησιμοποιώντας ληπτές και ρυθμιστές και να εφαρμόσετε άλλες δυνατότητες όπως απόδειξη εργασίας, εξόρυξη ή οποιαδήποτε άλλη έννοια που εξηγήσαμε στο άρθρο Βασικές αρχές Εξόρυξης Bitcoin.

συμπέρασμα

Το Blockchain είναι η τεχνολογία πίσω από το Bitcoin, το Etherium και κάθε άλλο κρυπτονόμισμα εκεί έξω. Σε αυτό το άρθρο, μάθατε πώς να δημιουργείτε ένα Blockchain με Python χρησιμοποιώντας αλγόριθμους κατακερματισμού όπως sha256, κλάσεις και αντικείμενα.

Η πρόκληση σας είναι να δημιουργήσετε ένα σύστημα εξόρυξης και γιατί όχι, να το εφαρμόσετε με ένα REST API χρησιμοποιώντας πλαίσια όπως το Django ή το Flask.

Πολλοί άνθρωποι κάνουν περιουσίες από κρυπτονομίσματα. Φανταστείτε τι θα μπορούσατε να κάνετε αν δημιουργήσετε ένα μόνοι σας. 🤑

Συνεχίστε την κωδικοποίηση! 👨‍💻