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

Практикум — шаг 3: ledger и переводы

Разработчику Аналитику

← Шаг 2 · Шаг 3 · Шаг 4 →

Собираем Ledger — объект, который связывает блокчейн, подписи и «биржевой» слой балансов. Это упрощённая модель spot-перевода без стакана заявок.


Модель балансов

balances: dict[str, dict[str, float]] # address -> asset -> amount
  • Актив по умолчанию — LAB (учебный токен).
  • При create_wallet начисляется стартовый баланс (как testnet faucet).
  • Реальные сети хранят состояние в реестре; CEX — в SQL. Здесь состояние в памяти, а в блок уходит журнал операций.

Mempool — очередь до блока

@dataclass
class Mempool:
pending: list[Transfer] = field(default_factory=list)

def drain(self) -> list[dict[str, Any]]:
batch = [tx.to_dict() for tx in self.pending]
self.pending.clear()
return batch

Аналогия с mempool в Bitcoin: транзакция сначала ожидает, затем майнер (у нас — метод mine_pending) включает пакет в блок.


submit_transfer — сквозной путь

def submit_transfer(self, sender, recipient, asset, amount) -> tuple[bool, str]:
ok, reason = self.compliance.check_transfer(sender, recipient, amount)
if not ok:
return False, reason
if self.balances[sender].get(asset, 0) < amount:
return False, "недостаточно средств"
tx = Transfer(..., nonce=self.nonces[sender])
tx.sign(self.keys[sender])
self.mempool.add(tx)
return True, "в mempool"

Порядок проверок намеренный:

  1. Compliance (регуляторика до движения денег).
  2. Баланс (бизнес-правило).
  3. Подпись (криптографическое авторство).

mine_pending — финализация

def mine_pending(self) -> tuple[bool, str]:
batch = self.mempool.drain()
for raw in batch:
# списание / зачисление
self.compliance.record_successful_transfer(sender, amount)
self.blockchain.mine_block(batch)
return True, f"добавлен блок #{self.blockchain.last_block.index}"

После майнинга:

  • балансы обновлены;
  • nonce отправителя увеличен;
  • блок добавлен в цепь с PoW.

Соберите в demo.py короткий сценарий: два кошелька, перевод 50 LAB, майнинг, затем попытка перевода 5000 без enhanced KYC. Ожидаемое поведение: первый перевод в mempool и в блоке, второй отклонён compliance, blockchain.is_valid()True.


Сравнение с криптотрейдингом

ОперацияLedger LabБиржа (CEX)
Депозитfaucet / стартовый балансБанковский перевод / on-chain deposit
Выводsubmit_transfer + mineВывод + проверки AML
Сделка spotПеревод актива между адресамиСделка в matching engine
ИсторияЦепочка блоков + auditТаблицы trades + отчёты

Стакан заявок (order book), маржа и деривативы в практикум не входят — их можно добавить отдельным модулем order.py (см. шаг 4).


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

  1. Создайте два кошелька, переведите 25 LAB, смайньте блок, выведите balances.
  2. Отправьте второй перевод с тем же nonce вручную (скопируйте Transfer) — обсудите, почему нужен учёт nonce.
  3. Добавьте актив BTC в balances и перевод между активами (потребуется расширить Transfer).

После шага 4 добавьте pytest-сценарий «успешный перевод после KYC basic».


Что дальше

Шаг 4 — compliance, аудит и автотесты.

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").