Перейти к основному содержимому

Практикум — шаг 1: цепочка блоков

Разработчику

← Обзор практикума · Шаг 1 · Шаг 2 →

Создаём ядро реестра — блок, хеш, цепочка и простейший proof-of-work. Логика совпадает с интерактивом на вводной странице, но здесь — полноценный Python-модуль.


Файлы этого шага

В каталоге из обзора создайте пакет ledger_lab/ и два файла:

  • block.py — блок и хеширование;
  • chain.py — цепочка, проверка и учебный PoW.

В начале block.py понадобятся импорты — hashlib, json, time, dataclasses.


Блок и канонический JSON

Хеш должен считаться от однозначного представления данных. Используем json.dumps с sort_keys=True:

def canonical_json(data: Any) -> str:
return json.dumps(data, sort_keys=True, separators=(",", ":"))

def sha256_hex(payload: str) -> str:
return hashlib.sha256(payload.encode("utf-8")).hexdigest()

Класс Block хранит index, previous_hash, timestamp, transactions, nonce. После заполнения полей вычисляется hash:

@dataclass
class Block:
index: int
previous_hash: str
timestamp: float
transactions: list[dict[str, Any]]
nonce: int = 0
hash: str = field(default="", init=False)

def calculate_hash(self) -> str:
return sha256_hex(canonical_json(self.header_dict()))

Genesis-блок — нулевой блок с фиксированным previous_hash из нулей (как в Bitcoin, только упрощённо):

def genesis_block() -> Block:
return Block(
index=0,
previous_hash="0" * 64,
timestamp=time.time(),
transactions=[{"type": "genesis", "message": "Crypto Ledger Lab"}],
)
Связь с теорией

В Bitcoin заголовок богаче (Merkle root, bits, version). У нас в transactions пока лежит весь список операций — для учебного объёма этого достаточно. Merkle-дерево разобрано в главе 1.


Цепочка и проверка

Blockchain держит список блоков и параметр difficulty (сколько hex-нулей в начале хеша):

Код ITЗагрузка примера кода…

Если изменить transactions в старом блоке без пересчёта hash и перемайнинга хвоста — is_valid() вернёт ошибку. Это тот же принцип, что в демо BlockchainChainPlay, когда подмена ломает цепочку.


Учебный майнинг (PoW)

Код ITЗагрузка примера кода…

difficultyПоведение
1Быстро, подходит для тестов
2Заметная задержка на ноутбуке
4+Наглядно показывает цену PoW

В Ethereum после Merge консенсус — PoS; PoW здесь только чтобы почувствовать работу майнера из обзора консенсуса.


Практическое задание

  1. В REPL или маленьком скрипте создайте Blockchain(difficulty=1), добавьте блок с транзакцией {"type": "transfer", "amount": 42}.
  2. Вызовите is_valid() до и после ручной подмены transactions в блоке 1.
  3. Увеличьте difficulty до 3 и засеките время mine_block.

Проверка в REPL после mine_block:

ok, msg = chain.is_valid()
assert ok, msg

Что дальше

Шаг 2 — криптография и подписи переводов: ключи Ed25519 и защита секрета в "vault".