Як створити блокчейн за допомогою Python?

Чи знаєте ви, що біткойн побудований на Blockchain? Сьогодні ми збираємося побудувати Blockchain з Python з нуля.

Що таке Blockchain?

У 2008 році Bitcoin папір був опублікований невідомою особою чи групою на ім’я Сатоші Накамото. Біткойн з’явився як однорангова версія електронної готівки, яка дозволяла проводити операції без проходження через централізовані установи (банки). Більшість людей не знають, що в тій самій статті Сатоші визначив розподілений спосіб зберігання інформації, сьогодні відомий як Blockchain.

Технологія блокчейн

Простіше кажучи, Blockchain — це спільна, незмінна цифрова книга, яка зберігає транзакції через децентралізовану мережу комп’ютерів.

Ми можемо розділити блокчейн на два простих терміни:

  • Блок: простір, де ми зберігаємо транзакції
  • Ланцюжок: набір пов’язаних записів

Це визначає Blockchain як ланцюжок пов’язаних блоків, де кожен блок зберігає транзакцію, здійснену з певними параметрами.

Кожен блок будується поверх іншого блоку, створюючи незворотний ланцюжок блоків. Іншими словами, кожен блок залежить від іншого. Це виходить у надійну та незмінну систему, у якій будь-хто з відповідними дозволами може перевірити цілісність.

Blockchain пропонує цікавий набір функцій:

  • Незмінність історії
  • Інформаційна стійкість
  • Немає помилок із збереженими даними

Зараз багато систем покладаються на блокчейн, наприклад криптовалюти, передача активів (NFT) і, можливо, у найближчому майбутньому, голосування.

Варто зазначити, що блокчейн Python не повинен бути складною програмою з тисячами рядків коду. За своєю суттю це буде список транзакцій, пов’язаних одна з одною.

Звичайно, це було коротке пояснення, але якщо вам потрібен повний посібник, ми підготували повний підручник з Blockchain для початківців. Обов’язково перевірте це.

Не зволікаючи, давайте створимо простий блокчейн на Python.

Створення блокчейна за допомогою Python

Перш ніж почати, давайте визначимо, що ми будемо робити в цьому підручнику:

  • Створіть просту систему Blockchain, написану на Python
  • Використовуйте наш блокчейн із попередньо встановленими транзакціями, представленими у вигляді рядків
  • Перевірте незмінність нашого Blockchain

Ми будемо використовувати не JSON, а списки Python. Це дозволить нам спростити процес і зосередитися на застосуванні ключових концепцій блокчейна.

Що вам знадобиться для виконання цього підручника:

Створення класу Block

Відкрийте свій улюблений редактор коду та створіть файл main.py. Це буде файл, з яким ми будемо працювати.

Тепер імпортуйте хешліб, модуль, який дозволяє створювати односторонні зашифровані повідомлення. Методи криптографії, такі як хешування, дозволяють Blockchain створювати безпечні транзакції.

Хеш-функція — це алгоритм, який бере деякі дані (зазвичай закодований рядок) і повертає унікальний ідентифікатор, який часто називають «дайджест» або «підпис». Ця остання частина є життєво важливою; з хеш-функцією невелика різниця у вхідних даних створює радикально інший ідентифікатор як вихід. Пізніше ми побачимо це в дії.

  Як зробити будильник гучнішим

Наразі просто імпортуйте хеш-ліб вбудованого модуля:

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

import hashlib

Цей модуль містить більшість алгоритмів хешування, які вам знадобляться. Майте на увазі, що ми будемо використовувати функцію hashlib.sha256().

Тепер давайте перейдемо до GeekCoinBlock, нашої абсолютно оригінальної назви блокчейну.

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.

Цей метод має три параметри:

  • self (примірник кожного об’єкта)
  • previous_block_hash (посилання на попередній блок)
  • transaction_list (список транзакцій, здійснених у поточному блоці).

Ми зберігаємо попередній хеш і список транзакцій і створюємо змінну екземпляра block_data як рядок. Цього не відбувається зі справжніми криптовалютами, у яких ми зберігаємо такі дані як інший хеш, але для спрощення ми зберігатимемо кожен блок даних як рядок.

Нарешті, ми створюємо block_hash, який інші блоки використовуватимуть для продовження ланцюжка. Ось де хешліб стане в нагоді; замість того, щоб створювати спеціальну хеш-функцію, ми можемо використовувати попередньо створений sha256 для створення незмінних блоків.

Ця функція отримує закодовані рядки (або байти) як параметри. Ось чому ми використовуємо метод block_data.encode(). Після цього ми викликаємо hexdigest(), щоб повернути закодовані дані в шістнадцятковий формат.

Я знаю, що все це може бути непосильним, тому давайте пограємо з хешлібом на оболонці 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» правдивий.

  7 найкращих програм для віддаленого моніторингу та керування (RMM) для SMB

Використання нашого Block Class

Пізніше ми створимо цілий клас 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 блоку genesis (перший блок, який передує іншим блокам) завжди буде деяким довільним рядком або хешем, у цьому випадку «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 хеші символів, але це майже відновлює механізм блокчейну.

Ви починаєте з блоку генезису, основи всіх інших блоків.

Будь-хто може підтвердити цілісність ланцюга, і тому блокчейн є такою безпечною системою. Наприклад, якщо ми трохи змінюємо вміст транзакції, скажіть:

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.

Давайте почнемо з видалення наших попередніх транзакцій і блокування об’єктів, а потім використаємо наведений нижче код.

# 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».
  • create_block_from_transaction — Це дозволяє нам додавати блоки до ланцюжка лише за допомогою списку транзакцій. Було б дуже неприємно створювати блок вручну кожного разу, коли ми хочемо записати транзакцію
  • display_chain — друкує ланцюжок блоків із циклом for
  • last_block — властивість, яка дозволяє отримати доступ до останнього елемента ланцюжка. Ми використали його в методі create_block_from_transaction.
  Як обчислити середньозважене значення в Excel

Давайте перевіримо цей блокчейн.

# 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 з нуля.

Тепер ви можете посилити незмінність блокчейну, використовуючи геттери та сетери, а також реалізувати інші функції, такі як підтвердження роботи, майнінг або будь-яку іншу концепцію, яку ми пояснили в статті про основи майнінгу біткойнів.

Висновок

Блокчейн — це технологія, яка лежить в основі біткойна, ефіріуму та будь-якої іншої криптовалюти. У цій статті ви дізналися, як створити блокчейн на Python за допомогою хеш-алгоритмів, таких як sha256, класів і об’єктів.

Ваше завдання полягає в тому, щоб створити систему майнінгу, а чому б і ні, реалізувати її за допомогою REST API за допомогою таких фреймворків, як Django або Flask.

Багато людей заробляють статки на криптовалютах. Тільки уявіть, що ви можете зробити, якщо створите його самостійно. 🤑

Продовжуйте кодувати! 👨‍💻