Доказательство работы и майнинг

Майнинг звучит загадочно, но в основе — простая головоломка: подобрать число так, чтобы хеш блока начинался с нескольких нулей. Сейчас сами «помайним».

Зачем вообще что-то «майнить»

В блокчейне без банка нужен способ решить, кто добавит следующий блок, и сделать подделку дорогой. Доказательство работы (proof-of-work) требует потратить вычислительные усилия: найти решение трудно, а проверить — легко. Это как судоку: решать долго, проверить мгновенно.

Головоломка с нулями

Хеш данных выглядит случайно. Майнер добавляет к блоку число nonce и хеширует снова и снова, перебирая nonce, пока хеш не начнётся, скажем, с трёх нулей. Угадать заранее нельзя — только перебор.

import hashlib

def block_hash(data, nonce):
    return hashlib.sha256(f"{data}|{nonce}".encode()).hexdigest()

data = "Блок №7: Аня -> Боре 5 монет"
# Покажем, как хеш скачет при разных nonce
for nonce in range(5):
    print(f"nonce={nonce}: {block_hash(data, nonce)}")
print("Хеш непредсказуем — нельзя угадать нужный nonce, только перебирать")

Майнинг-демо: ищем хеш с нулями

Сложность задаётся числом ведущих нулей. Чем больше нулей — тем дольше поиск.

import hashlib, time

def mine(data, difficulty):
    target = "0" * difficulty
    nonce = 0
    start = time.time()
    while True:
        h = hashlib.sha256(f"{data}|{nonce}".encode()).hexdigest()
        if h.startswith(target):
            elapsed = time.time() - start
            return nonce, h, elapsed
        nonce += 1

data = "Блок №7: Аня -> Боре 5 монет"
for difficulty in (1, 2, 3, 4):
    nonce, h, t = mine(data, difficulty)
    print(f"{difficulty} нуля: nonce={nonce:<7} hash={h[:16]}... за {t:.3f} сек")

Видно, как с каждым нулём поиск резко удлиняется. В сети Bitcoin нулей нужно гораздо больше, и над задачей трудятся миллионы устройств.

Проверить — мгновенно

import hashlib

data = "Блок №7: Аня -> Боре 5 монет"
nonce = 0
while True:
    h = hashlib.sha256(f"{data}|{nonce}".encode()).hexdigest()
    if h.startswith("000"):
        break
    nonce += 1

print("Майнер нашёл nonce:", nonce)
# Любой проверяет ОДНИМ хешем:
check = hashlib.sha256(f"{data}|{nonce}".encode()).hexdigest()
print("Проверка хеша:", check[:16], "...")
print("Начинается с 000?", check.startswith("000"))

Зачем это нужно

Чтобы переписать старый блок, жулику пришлось бы заново «прорешать» головоломки для него и всех последующих блоков, обгоняя при этом всю остальную сеть. Это требует колоссальных ресурсов — поэтому подделка экономически бессмысленна. Так proof-of-work защищает блокчейн. Главный минус — огромный расход энергии, из-за чего появились другие подходы (например, proof-of-stake).

Вывод:

Proof-of-work — головоломка: перебором nonce найти хеш блока с нужным числом ведущих нулей. Решать трудно (нужно много вычислений), проверять — один хеш. Это делает подделку прошлого слишком дорогой, но тратит много энергии.
Проверьте себя
1. В чём суть головоломки доказательства работы (proof-of-work)?
AУгадать пароль владельца кошелька
BПеребором nonce найти хеш блока, начинающийся с нужного числа нулей
CРасшифровать чужую транзакцию
DСкачать весь блокчейн как можно быстрее
2. Почему proof-of-work защищает блокчейн от подделки прошлого?
AПотому что блоки зашифрованы
BПереписать старый блок требует заново прорешать головоломки для него и всех следующих блоков, обгоняя всю сеть — это слишком дорого
CПотому что старые блоки нельзя прочитать
DПотому что майнинг бесплатный
Поддержать проект