montana/Монтана-Протокол/Архив/TimeChain v12.0.0.md

880 lines
53 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TimeChain — Спецификация протокола Montana
**Версия:** 12.0.0 (2026-04-01)
## Определение
Децентрализованная сеть. Время — единственная реальная валюта. 1 секунда присутствия узла в сети = 1 Ɉ.
Консенсус: **Proof of Time (PoT)** — последовательное SHA-256 хэширование (VDF) как доказательство прошедшего времени. Временные окна возникают из вычислений.
Генезис: 09.01.2026 00:00:00 MSK.
---
## Криптография
Два примитива с разделёнными ролями:
- **SHA-256** — консенсус (Beacon VDF, Service VDF), адреса, Merkle-деревья, хэширование
- **FN-DSA-512** (selected NIST candidate, forthcoming FIPS 206) — подписи транзакционных блоков
SHA-256 обеспечивает квантовую устойчивость консенсуса: алгоритм Гровера сокращает безопасность с 256 до 128 бит. FN-DSA-512 обеспечивает математическую постквантовую устойчивость подписей на основе NTRU-решёток.
### Подписи — FN-DSA-512
Подпись на NTRU-решётках (Falcon-512). Stateless, многоразовая. Публичный ключ закрепляется за аккаунтом при создании и используется для всех последующих блоков.
| Компонент | Размер |
|-----------|--------|
| Приватный ключ | 1 281B |
| Публичный ключ | 897B |
| Подпись (padded) | 666B |
Поле suite_id в формате блока обеспечивает миграцию подписи без изменения модели состояния. Активация новой схемы требует protocol upgrade. Активная схема на момент запуска: FN-DSA-512.
### Адреса
Формат: `mt` + Base58(account_id + checksum).
Account_id = SHA-256("mt-account" || suite_id || pubkey). Стабильный идентификатор аккаунта. Смена ключа или схемы подписи выполняется через ChangeKey блок без изменения account_id — для этого account_id привязан к первому pubkey, а текущий ключ хранится в состоянии аккаунта.
---
## Account Chain (Block Lattice)
Каждый аккаунт имеет собственную цепочку блоков. Перевод — один блок в цепочке отправителя. Зачисление получателю — детерминированно после финализации IC/QC. Цепочки аккаунтов полностью независимы.
### Типы блоков
**OpenAccount** — создание аккаунта (один раз):
```
type 1B
suite_id 2B
account_id 32B
pubkey 897B ← FN-DSA-512, публикуется единожды
pending_root 32B ← Merkle root всех захваченных pending entries
balance 8B ← детерминированно = сумма захваченных entries (≥ ACCOUNT_RESERVE)
signature 666B
Итого: ~1 638B
```
**StateBlock** — перевод:
```
prev_hash 32B ← хэш предыдущего блока в цепочке аккаунта
account_id 32B
link 32B ← account_id получателя
link_amount 8B ← сумма перевода получателю
balance 8B ← абсолютный баланс отправителя после операции
flags 1B
signature 666B
Итого: ~779B
```
**ChangeKey** — смена ключа или схемы подписи:
```
prev_hash 32B
account_id 32B
new_suite_id 2B
new_pubkey 897B ← новый публичный ключ
signature 666B ← подписано старым ключом
Итого: ~1 629B
```
### Верификация баланса
Баланс в StateBlock абсолютный. StateBlock содержит поле balance (новый баланс отправителя после операции). Перевод содержит сумму в поле link_amount (8B, добавляется в формат StateBlock).
```
fee = prev_balance - new_balance - link_amount
```
Каждый узел проверяет: new_balance ≥ 0, link_amount > 0, fee ≥ min_fee.
### Комиссия
Комиссия вычисляется из трёх известных величин: prev_balance (из Account Table), new_balance и link_amount (из StateBlock). Минимум 1 mɈ. Размер min_fee адаптивный — рассчитывается по формуле на основе заполненности окон τ₁. Пользователь знает комиссию до отправки.
Победитель окна τ₂ получает сумму всех комиссий блоков в окне.
### Pending Transfers и OpenAccount
Отправка на несуществующий account_id создаёт pending entry в Pending Transfer Table:
```
Pending entry:
source_block_hash 32B
from_account_id 32B ← отправитель (для refund при expiry)
to_account_id 32B
amount 8B
expiry_τ₂ 4B ← дедлайн: N окон τ₂ после финализации
```
Баланс отправителя уменьшается сразу при финализации StateBlock. Средства хранятся в pending entry до открытия аккаунта получателем.
OpenAccount захватывает все pending entries адресованные данному account_id. Canonical rule: множество захваченных entries = все записи в Pending Transfer Table где `to_account_id == account_id`. Выбора нет — захватываются все или ни одна. pending_root в OpenAccount = Merkle root этого множества, отсортированного по (source_block_hash). balance = сумма amount всех захваченных entries.
Верификация OpenAccount в state transition:
1. Вычислить множество entries из Pending Transfer Table по to_account_id
2. Вычислить Merkle root множества → сравнить с pending_root в блоке
3. Вычислить сумму amount → сравнить с balance в блоке
4. Проверить balance ≥ ACCOUNT_RESERVE
5. Удалить все matching entries из Pending Transfer Table
6. Создать запись в Account Table
Автоматический возврат: если pending entry не захвачена OpenAccount до expiry_τ₂, средства возвращаются отправителю протокольно в state transition. Новая подпись отправителя не требуется.
### Account Reserve
ACCOUNT_RESERVE Ɉ — минимальная сумма для открытия аккаунта (параметр протокола). Защита от спама аккаунтов.
### Coinbase
Победитель τ₂ создаёт coinbase-блок в своей цепочке. Баланс увеличивается на сумму эмиссии + комиссии всех блоков окна.
Supply audit при финализации τ₂: суммарная эмиссия coinbase от генезиса сверяется с supply(height) из issuance schedule.
### Двойная трата
Каждый аккаунт имеет одну цепочку. Два блока с одним prev_hash = форк. Форк обнаруживается мгновенно. Разрешается QC (>2/3 активного веса голосует за каноничный блок).
---
## Состояние сети
Глобальное состояние = Account Table + Node Table + Pending Transfer Table + Expiry Queue.
```
Account Table (запись на аккаунт):
account_id 32B
balance 8B
frontier_hash 32B ← хэш последнего блока в цепочке
block_height 4B
suite_id 2B
current_pubkey 897B
Node Table (запись на узел):
node_id 32B ← SHA-256("mt-node" || node_pubkey), верифицируемо
node_pubkey 897B
suite_id 2B
chain_length 4B ← количество подписанных τ₂, weight = min(chain_length, MAX_WEIGHT)
cooldown_expires_τ₂ 4B ← 0 если cooldown пройден
checkpoint_equivocation 1B ← 0 или 1 (прогрессивный counter)
status 1B ← active | cooldown | suspended
Pending Transfer Table (запись на pending перевод):
source_block_hash 32B
from_account_id 32B ← для refund при expiry
to_account_id 32B
amount 8B
expiry_τ₂ 4B
Expiry Queue (индекс pending entries по сроку):
expiry_τ₂ 4B
entry_hash 32B
```
### State Root
Merkle-дерево глобального состояния. Четыре подкорня, каждый — Merkle root своей таблицы с явным порядком листьев:
```
State Root = SHA-256("mt-merkle-node" || account_root || node_root || pending_root || expiry_root)
Account Table Root: листья по account_id (лексикографически)
Node Table Root: листья по node_id (лексикографически)
Pending Transfer Root: листья по (to_account_id || from_account_id || source_block_hash) (лексикографически)
Expiry Queue Root: листья по (expiry_τ₂ big-endian 4B || entry_hash) (лексикографически)
active_set_root = Merkle root подмножества Node Table где status = active
и cooldown_expires_τ₂ < current_τ₂.
Детерминировано из Global State.
```
Все sort keys фиксированной длины. Побайтовое лексикографическое сравнение. Две реализации с одинаковыми данными строят одинаковое дерево и получают одинаковый State Root.
State Root коммитится в заголовке каждого финализированного proposal τ₂.
---
## Таймчейн
Три логических двигателя с односторонним потоком зависимостей: Beacon → Service → Execution.
### Beacon — глобальные часы протокола
Непрерывная последовательная SHA-256 цепочка. Общий источник случайности и ритм сети:
```
B_r = SHA-256^D(B_{r-1})
```
D — количество последовательных хэшей за один слот τ₁. Beacon продвигается по расписанию финализированных слотов. Для фиксированного индекса r значение B_r совпадает у всех честных узлов. Каждый узел вычисляет Beacon независимо — результат детерминирован.
Beacon не зависит от состояния, транзакций и поведения отдельных узлов.
### Service — персональный VDF узла
Доказательство непрерывного присутствия конкретного node_id. Якорится в Beacon каждый слот:
```
S_{i,s,0} = SHA-256(S_{i,s-1,m} || B_s || node_id_i)
S_{i,s,j+1} = SHA-256(S_{i,s,j}) для j = 0..m-1
```
Три компонента seed: предыдущий endpoint (непрерывность службы), значение Beacon (протокольное время), node_id (идентичность). m последовательных хэшей за слот — доказательство работы.
Service зависит от Beacon. Beacon не зависит от Service.
### Execution — содержимое блока
Приём, верификация execution objects и формирование канонического набора. Execution objects бывают четырёх типов:
| Тип | Описание | Валидация |
|-----|----------|-----------|
| StateBlock | Перевод средств | FN-DSA-512 подпись, баланс ≥ 0, prev_hash, link_amount > 0, fee ≥ min_fee |
| OpenAccount | Создание аккаунта | FN-DSA-512 подпись, pending_root, balance ≥ ACCOUNT_RESERVE |
| ChangeKey | Смена ключа | FN-DSA-512 подпись старым ключом, new_pubkey |
| NodeRegistration | Регистрация узла | FN-DSA-512 подпись, node_id уникален |
| EquivocationProof | Доказательство equivocation | Два конфликтующих подписанных сообщения от одного node_id |
Все типы проходят одинаковый IC pipeline: валидатор проверяет объект по правилам своего типа, включает H(object) в checkpoint body/blocks_root. IC достигается при >2/3 активного веса.
#### Inclusion Certificate (IC)
IC — пороговое свойство, не отдельный объект. Блок B имеет IC на слоте s при выполнении условия:
```
IC(B, s) = true
Σ weight(v), где существует slot s' ≤ s такой что
CP_{v,s'} валиден и H(B) доказуемо входит в blocks_root(CP_{v,s'})
>
2/3 × Σ weight(active_set)
```
Вес считается по уникальным валидаторам. Один валидатор — один голос, независимо от количества слотов в которых он подтвердил блок.
#### Data availability
Валидатор v включает H(obj) в checkpoint body только при выполнении условий:
1. Валидатор получил полный execution object
2. Проверил объект по правилам валидации его типа (таблица выше)
3. Включил H(obj) в checkpoint body и blocks_root
Data availability обеспечивается порогом IC: execution object набирает IC только если >2/3 активного веса независимо получили, проверили и включили его в свои чекпоинты. Один валидатор не может протолкнуть невидимый объект через IC. Отдельного наказания за data unavailability нет — отсутствие ответа на запрос не является криптографически доказуемым фактом.
#### Канонический набор
Канонический набор τ₂ = все блоки B где IC(B) достигнут до cutoff последнего слота окна. Канонический порядок: (earliest_certified_slot, H(B)). Детерминирован — каждый честный узел приходит к одному и тому же набору. Конфликты (форки аккаунтов) разрешаются правилом first valid in canonical order wins.
#### Proposer
Победитель лотереи вычисляет канонический набор детерминированно, добавляет coinbase. Содержимое proposal определено правилами IC и каноническим порядком. Свобода proposer: ноль. Отклонение от правил — невалидный proposal, переход ко второму месту. Любой узел независимо вычисляет тот же набор.
#### Верификация и финальность
Каждый валидатор независимо вычисляет канонический набор из собранных чекпоинтов. Если blocks_root в proposal совпадает с собственным вычислением → подписывает QC. Не совпадает → отклоняет.
QC на proposal header финализирует конкретный blocks_root и new_state_root. QC достаточен для финальности канонического набора. QC не является доказательством индивидуального IC каждого блока.
#### State transition
При финализации proposal state transition применяется атомарно в фиксированном порядке:
```
apply_proposal(state, proposal) → state':
Шаг 1: применить блоки канонического набора в порядке (earliest_certified_slot, H(B)).
StateBlock: обновить баланс отправителя.
Получатель существует → кредитовать баланс.
Получатель не существует → создать pending entry.
OpenAccount: захватить все pending entries для account_id
(включая созданные ранее на этом же шаге),
создать запись в Account Table.
ChangeKey: обновить pubkey и suite_id в Account Table.
NodeRegistration: создать запись в Node Table (chain_length=0, status=cooldown).
EquivocationProof: применить санкцию к node_id в Node Table
(checkpoint: counter++, cooldown / QC: status=suspended, chain_length=0).
Шаг 2: применить coinbase победителя.
Шаг 3: обновить chain_length.
Для каждого node_id опубликовавшего ≥ k валидных чекпоинтов в этом τ₂:
chain_length += 1 в Node Table.
Для узлов с cooldown_expires_τ₂ ≤ current_τ₂ и status = cooldown:
status = active.
Шаг 4: обработать expiry refunds.
Все pending entries где expiry_τ₂ ≤ current_τ₂
и не захваченные OpenAccount на шаге 1 →
вернуть amount на баланс from_account_id (поле в pending entry),
удалить entry из Pending Transfer Table и Expiry Queue.
Шаг 5: вычислить new_state_root.
```
Порядок детерминирован. Блоки первыми в каноническом порядке, coinbase вторым, chain_length третьим, expiry refunds последними. OpenAccount видит pending entries созданные ранее в том же τ₂. Каждый узел применяет одну и ту же последовательность шагов к одному и тому же набору блоков и получает один и тот же new_state_root. Отдельный receive-блок от получателя не требуется.
Execution зависит от Beacon и Service. Обратных зависимостей нет.
С ростом TPS сети дополнительные ядра подключаются для верификации блоков. Минимум для валидатора: 3 логических ядра (Beacon + Service + Execution). Верификация блоков аккаунтов полностью параллелизуется — цепочки аккаунтов независимы.
### Чекпоинт
Каждый валидатор в каждом слоте τ₁ публикует подписанный чекпоинт:
```
CheckpointHeader:
Sig_v(epoch, slot, B_s, S_{v,s,m}, blocks_root, block_count)
CheckpointBody:
block_hashes[] ← H(B) отсортированные лексикографически
(побайтовое сравнение), из которых строится blocks_root
```
CheckpointBody распространяется по P2P вместе с header. Без body чекпоинт неполон. blocks_root = Merkle root из block_hashes[] в заданном порядке. Membership proof: Merkle proof что H(obj) является листом в blocks_root.
Чекпоинт связывает протокольное время (B_s), доказательство службы (S_{v,s,m}) и проверенные execution objects (blocks_root + body) в одну подписанную аттестацию.
### QCVote
Голос узла за proposal при финализации τ₂:
```
QCVote:
node_id 32B
τ₂_index 4B
proposal_hash 32B ← SHA-256("mt-header" || proposal_header)
signature 666B ← FN-DSA-512, подписано node_pubkey
```
QC = набор QCVote с суммарным weight > 2/3 × Σ weight(active_set). EquivocationProof для qc_conflict содержит два QCVote с одинаковым (node_id, τ₂_index) и разным proposal_hash.
### Регистрация узла
Регистрация — каноническое событие в state transition. Новый узел появляется в сети через NodeRegistration:
```
NodeRegistration:
type 1B
suite_id 2B
node_pubkey 897B ← FN-DSA-512 ключ узла для подписи чекпоинтов и QC
signature 666B ← подписано node_pubkey
Итого: ~1 566B
```
node_id = SHA-256("mt-node" || node_pubkey). Вычисляется детерминированно из публичных данных. Верифицируемо любым узлом.
NodeRegistration проходит IC и включается в канонический набор τ₂ как execution object. При финализации state transition создаёт запись в Node Table: node_id, node_pubkey, suite_id, chain_length = 0, status = cooldown, cooldown_expires_τ₂ = current_τ₂ + cooldown (рассчитанный по формуле Adaptive Cooldown). checkpoint_equivocation = 0.
Счётчик new_registrations_in_τ₃ в формуле Adaptive Cooldown = количество финализированных NodeRegistration в данном периоде τ₃.
### Входной барьер — Adaptive Cooldown
Допуск к консенсусу определяется Adaptive Cooldown — динамическим входным периодом, чувствительным к темпу роста сети.
#### Формула
Скользящее окно из 3 последних τ₃ (42 дня). Темп роста — процент новых регистраций от количества активных узлов. Медиана трёх последних значений определяет норму:
```
growth_rate = new_registrations_in_τ₃ / active_nodes_at_start × 100%
median = median(growth_rate за 3 предыдущих τ₃)
excess = ((current_growth - median) / median) × 100%
excess ≤ 0%: cooldown = 7 дней
0% < excess ≤ 100%: cooldown = 7 + excess × 35 / 100
excess > 100%: cooldown = 42 дня
```
Минимум 7 дней. Максимум 42 дня (3 × τ₃).
Bootstrap: `effective_median = max(median, 1%)`, `effective_active = max(active_nodes, 10)`.
#### Асимметрия
Повышение cooldown — немедленное, без ограничений. Снижение — не быстрее 20% за τ₃. Атака поднимает барьер мгновенно. Возврат к норме занимает месяцы.
#### Реакция внутри τ₃ и фиксация
Cooldown для NodeRegistration вычисляется в момент финализации по одной переменной — effective_growth:
```
projected_growth = current_registrations / elapsed_fraction
elapsed_fraction = elapsed_slots / total_slots_in_τ₃
effective_growth = max(growth_rate_last_τ₃, projected_growth)
```
effective_growth подставляется в формулу cooldown. Счётчик current_registrations = количество финализированных NodeRegistration с начала текущего τ₃ в каноническом порядке (slot, H(obj)).
Cooldown закрепляется за узлом в момент финализации его NodeRegistration. Пересчёт не меняет cooldown уже зарегистрированным узлам.
#### Во время cooldown
Узел запускает Beacon + Service VDF сразу при регистрации. Валидирует блоки, ретранслирует данные, публикует чекпоинты. Узел усиливает сетевой слой и несёт стоимость допуска к консенсусу. Стоимость каждого Sybil-узла: 1 service-core непрерывно на весь период cooldown.
#### После cooldown
Вес начинается с 0 и растёт линейно с каждым подписанным τ₂. Работа во время cooldown полезна сети, но не конвертируется в консенсусный вес.
---
## Потоковая модель
Блоки аккаунтов текут непрерывно. Узел получает блок → проверяет подпись FN-DSA-512 и баланс → передаёт в P2P gossip. Время подтверждения определяется скоростью P2P-распространения (~2-5 секунд).
Блок включается в канонический набор τ₂ при получении Inclusion Certificate (>2/3 активного веса подтвердили через чекпоинты). Блоки не ожидают появления τ₁ или τ₂ — окна являются чекпоинтами, а не условиями приёма.
Цепочки аккаунтов полностью независимы. Блоки разных аккаунтов обрабатываются параллельно без конфликтов.
---
## Временные слои (τ)
```
τ₁ (≈60с) → τ₂ (10 × τ₁) → τ₃ (2016 × τ₂) → τ₄ (~104 × τ₃)
```
### τ₁ — Слот (≈60 секунд)
- Beacon продвигается на D хэшей
- Service VDF продвигается на m хэшей с якорем в текущем B_s
- Валидаторы публикуют подписанные чекпоинты CP_{i,s}
- Узлы обмениваются чекпоинтами и блоками аккаунтов по P2P
- Блоки набирают Inclusion Certificates
### τ₂ — Финализация и эмиссия (10 × τ₁ ≈ 10 минут)
- Active set (состав и веса участников) фиксируется в начале τ₂
- Канонический набор: все блоки с валидным IC до cutoff последнего слота
- Лотерея: `ticket_i = S_{i,final,m} / weight_i`, победитель = min(ticket_i) среди допущенных
- Победитель публикует proposal с заголовком:
```
Proposal header:
prev_qc_hash 32B
prev_state_root 32B ← State Root до применения блоков
blocks_root 32B ← Merkle root канонического набора
new_state_root 32B ← State Root после применения всех блоков
active_set_root 32B
beacon_value 32B
coinbase_hash 32B
```
- Финальность: QC на proposal header от >2/3 активного веса. Каждый валидатор применяет блоки детерминированно и проверяет new_state_root
- При финализации: state transition по фиксированному порядку (см. раздел «State transition» в Execution)
- Seed следующей эпохи: `seed_i = SHA-256(B_r || active_set_root_r || node_id_i)`
- Coinbase: вся эмиссия + все комиссии → победителю
- Supply audit: суммарная эмиссия coinbase от генезиса сверяется с supply(height) из issuance schedule
- Разрешение форков: приоритет ветки с наибольшим суммарным Beacon-доказательством
Beacon safety: компрометация значения Beacon требует нарушения свойства последовательности SHA-256 VDF или подделки finality certificate порогом >2/3 активного веса.
Beacon liveness: задержка продвижения Beacon требует блокировки finality порогом >1/3 активного веса.
### τ₃ — Адаптация (2016 × τ₂ ≈ 14 дней)
- Калибровка D и m: медиана слотовых интервалов сверяется с целевыми, цель τ₁ ≈ 60 секунд
- State Root коммитится в каждом τ₂ (в proposal header). State Root покрывает весь Global State: Account Table, Node Table, Pending Transfer Table, Expiry Queue. τ₃ фиксирует канонический State Root для Fast Sync
- Криптографическая амнезия: заголовки τ₂ и QC сохраняются навсегда — верифицируемая цепочка state commitments. Тела блоков аккаунтов, подписи FN-DSA-512, IC proofs и данные чекпоинтов удаляются после 8 × τ₃ (112 дней). Заголовки доказывают что конкретное состояние было закоммичено консенсусом; восстановление содержимого состояния требует snapshot или архива. Equivocation и slashing proofs по объектам старше 8 × τ₃ не принимаются — все споры разрешаются внутри окна
- Пересчёт параметров окна τ₁
- Пересчёт Adaptive Cooldown
### τ₄ — Эпоха (~104 × τ₃ ≈ 4 года)
- Потолок веса: MAX_WEIGHT = количество τ₂ в одном τ₄
- Эмиссия постоянна: 600 Ɉ/τ₂ в каждой эпохе
---
## Консенсус — Proof of Time (PoT)
### Три двигателя
**Beacon** — глобальные часы. Чистая VDF-цепочка `B_r = SHA-256^D(B_{r-1})`. Источник случайности для лотереи. Продвигается по расписанию финализированных слотов.
**Service** — персональный VDF. Якорится в Beacon каждый слот. Доказывает непрерывное присутствие node_id. Определяет вес и лотерейный билет.
**Execution** — содержимое блока. Канонический набор определяется Inclusion Certificate (>2/3 активного веса). Порядок детерминирован. Победитель собирает proposal механически.
Зависимости односторонние: Beacon → Service → Execution. Отказ в Execution не заражает случайность. Отказ конкретного узла в Service не заражает общий ритм.
### Стаж и вес
#### Определение
Вес узла — длина его непрерывной Service цепочки, измеренная в подписанных τ₂:
```
weight_i = min(chain_length_i, MAX_WEIGHT)
MAX_WEIGHT = количество τ₂ в одном τ₄ (~105 000)
```
Вес — единственная мера влияния узла в протоколе. Определяется только временем непрерывной службы.
#### Как растёт
Цепочка растёт на 1 за каждый τ₂ с засчитанным участием. Участие в τ₂ засчитывается при публикации не менее k валидных чекпоинтов из n слотов окна (k=8, n=10). Чекпоинт валиден при выполнении условий: подписан ключом node_id, содержит корректные epoch и slot, якорится в соответствующий Beacon slot, получен сетью до конца следующего слота.
#### Обрыв
Если узел за период τ₃ отработал менее 1613 из 2016 окон τ₂ — цепочка обрывается, weight = 0. Узел начинает копить длину заново. Adaptive Cooldown повторно не проходится (node_id уже зарегистрирован).
#### Три зоны
- **Cooldown (7-42 дня):** допуск закрыт, weight = 0, узел работает как валидатор и ретранслятор
- **После cooldown — 4 года:** weight растёт линейно с каждым подписанным τ₂
- **4+ года (≥ τ₄):** weight = MAX_WEIGHT, потолок
Потолок τ₄ предотвращает бесконечный рост преимущества ранних участников. Все цепочки старше 4 лет равны между собой.
#### На что влияет вес
Вес определяет три вещи:
**1. Лотерея.** Вероятность победы в τ₂ пропорциональна весу:
```
ticket_i = S_{i,final,m} / weight_i
winner = min(ticket_i)
P(node_i) = weight_i / Σ weight(all_nodes)
```
Больше вес → меньше ticket → выше шанс. Узел с weight = 0 не участвует в лотерее.
**2. Голосовая сила в консенсусе.** Inclusion Certificate и Quorum Certificate считаются по весу:
```
IC валиден: Σ weight(подтвердивших) > 2/3 × Σ weight(active_set)
QC валиден: Σ weight(подписавших) > 2/3 × Σ weight(active_set)
```
Голос узла в IC и QC пропорционален его weight.
**3. Допуск.** weight = 0 означает: узел участвует в сети (валидация, ретрансляция), но не участвует в лотерее и не имеет голосовой силы в IC/QC.
### Победитель τ₂
Победитель определяется после закрытия окна τ₂. Каждый узел раскрывает свой Service VDF endpoint. Минимальный ticket среди допущенных — победитель.
Победитель публикует proposal: канонический набор блоков аккаунтов (определён IC) + coinbase. Содержимое proposal детерминировано правилами IC и каноническим порядком. Свобода победителя: ноль.
Финальность возникает после QC на заголовок proposal от >2/3 активного веса.
### Верификация
Победитель публикует: `{node_id, Service checkpoints[], proposal}`.
Верификация Service VDF: пересчёт K сегментов параллельно. K ≈ 960. На C ядрах: ~(K/C) × t_segment секунд. 8 ядер → ~7.5 сек. 64 ядра → ~1 сек.
Верификация proposal: независимый расчёт канонического набора по IC и сравнение с proposal.
### Устойчивость
- **Proposer grinding** исключён: победитель не выбирает состав блока, канонический набор определяется IC (>2/3 активного веса)
- **Committee grinding** исключён: Beacon не зависит от состояния и транзакций, seed лотереи строится из Beacon
- **Node_id гриндинг** исключён: Adaptive Cooldown (7-42 дня), Beacon неизвестен при регистрации
- **Предвычисление** исключено: seed содержит текущее значение Beacon
- **Replay** исключён: Beacon уникален для каждого τ₂
- **Аппаратное преимущество** ограничено: последовательное хэширование масштабируется тактовой частотой и IPC, а не количеством ядер или бюджетом
- **Sybil-барьер**: Adaptive Cooldown (7-42 дня, асимметричный) + Service VDF (физическое ядро) + линейный рост веса от нуля
- **Аристократия** ограничена: потолок веса τ₄, после 4 лет все равны
### Разрешение конфликтов и санкции
Два класса нарушений. Пользовательские конфликты разрешаются протокольными правилами без санкций. Валидаторский equivocation — через аннулирование конфликтующих сообщений и санкции пропорциональные классу опасности.
#### Пользовательские конфликты
**Двойной блок аккаунта** (два блока с одним prev_hash): разрешается правилом first valid in canonical order wins. Без санкции.
**Невалидный proposal**: валидаторы отклоняют, QC не формируется, переход ко второму месту. Без санкции.
#### Валидаторский equivocation
При обнаружении конфликтующих подписанных сообщений от одного node_id: оба аннулируются. Вес узла в IC/QC за этот слот/τ₂ = 0.
Checkpoint equivocation — конфликт определяется по одинаковым (node_id, epoch, slot) с разным blocks_root или иным checkpoint payload:
```
1-й раз: cooldown 7 дней, вес сохранён
2-й раз: cooldown 42 дня, weight = 0
```
QC double vote — конфликт определяется по двум разным proposal_header_hash от одного node_id в одном τ₂:
```
1-й раз: сразу cooldown 42 дня, weight = 0
```
Санкция вступает в силу с следующего τ₂. Active set текущего τ₂ зафиксирован в его начале и не меняется до закрытия. Уже финализированный QC не откатывается ретроактивно — узел наказывается prospectively.
#### Equivocation proof
```
EquivocationProof:
type 1B ← checkpoint_conflict | qc_conflict
node_id 32B
evidence_a ← первое подписанное сообщение
evidence_b ← второе конфликтующее подписанное сообщение
```
Публикует любой узел обнаруживший конфликт. Верификация: оба сообщения подписаны одним node_id с одинаковыми координатами и разным содержимым. Подписи FN-DSA-512 криптографически верифицируемы. Подделка невозможна.
Proof включается в канонический набор τ₂. При финализации state transition применяет санкцию к node_id. Checkpoint equivocation counter в Node Table: 0 → cooldown 7 дней, 1 → cooldown 42 дня + chain_length = 0. Counter сбрасывается после chain_length = 0 и перезапуска цепочки. QC double vote: сразу chain_length = 0 + cooldown 42 дня + status = suspended.
---
## Адреса и переводы
### Полный флоу перевода
```
1. Боб: кошелёк создаёт аккаунт → account_id (постоянный адрес)
2. Боб → Алисе: "отправь на mt4ZGfe..." (account_id)
3. Алиса формирует StateBlock в своей цепочке:
prev_hash: хэш её предыдущего блока
link: account_id Боба
link_amount: 50 Ɉ
balance: 49.999 Ɉ (100 - 50 - 0.001 fee)
4. Алиса подписывает FN-DSA-512
5. Алиса рассылает блок узлам сети
6. Каждый узел проверяет:
FN-DSA-512 подпись валидна для pubkey Алисы ✓
prev_hash совпадает с frontier Алисы ✓
fee = 100 - 49.999 - 50 = 0.001 Ɉ ≥ min_fee ✓
balance ≥ 0 ✓
link_amount > 0 ✓
7. Блок распространяется через P2P gossip
8. Блок получает IC (>2/3 валидаторов подтвердили в чекпоинтах)
9. При финализации τ₂:
Баланс Алисы: 50 Ɉ (из StateBlock)
Баланс Боба: увеличен на 50 Ɉ (детерминированно)
```
### Баланс
Баланс аккаунта — одно число в таблице аккаунтов. Обновляется при финализации: исходящие переводы (из StateBlock отправителя) и входящие зачисления (детерминированно по финализированным блокам).
Бэкап = seed (для деривации приватного ключа FN-DSA-512).
---
## Эмиссия
### Единица
1 секунда Montana = 1 $MONT = 1 Ɉ = 1 000 mɈ = 1 000 000 μɈ = 1 000 000 000 nɈ
Точность: 9 знаков после запятой (наносекунда). Все расчёты эмиссии в nɈ (целочисленная арифметика, без плавающей точки).
### Issuance schedule
Одна секунда протокольного времени порождает одну монету. С первого блока и навсегда.
| Параметр | Значение |
|----------|----------|
| Генезис | 09.01.2026 00:00:00 MSK |
| REWARD | 600 000 000 000 nɈ (600 Ɉ) |
### Функция награды
```
reward(height) = 600_000_000_000 nɈ
```
Каждое окно τ₂ длится 600 секунд и создаёт ровно 600 Ɉ. Без халвингов, без фаз, без исключений. Одна константа на весь горизонт существования сети.
### Supply audit
```
supply(height) = 600_000_000_000 × (height + 1) nɈ
```
Одно умножение. Проверяемо каждым узлом в каждом τ₂. O(1).
### Инфляция
Supply растёт линейно. Инфляция снижается асимптотически к нулю — константная эмиссия делится на растущий supply:
```
Год 1: 100%
Год 2: 50%
Год 5: 20%
Год 10: 10%
Год 50: 2%
Год 100: 1%
Год 1000: 0.1%
```
### Bootstrap
Ранние участники получают непропорционально большую долю через вероятность лотереи, а не через повышенную награду. При 10 узлах каждый побеждает примерно раз в 100 минут. При 100 000 — раз в 2 года. Bootstrap встроен в математику лотереи, а не в расписание эмиссии.
### Распределение
Победитель τ₂ получает всю эмиссию + все комиссии окна через coinbase-блок в своей цепочке. Одно правило. Неизменно с генезиса.
Базовый бюджет эмиссии постоянный в единицах протокола: 600 Ɉ/τ₂ + комиссии. Реальный бюджет безопасности в покупательной способности зависит от рынка.
1 Ɉ = 1 секунда описывает скорость эмиссии. Не ценовой peg, не гарантия покупательной способности.
---
## Пропускная способность
Размер StateBlock: ~779B.
| Канал узла | TPS |
|-----------|-----|
| 10 Mbps | ~1 620 |
| 100 Mbps | ~16 200 |
| 1 Gbps | ~162 000 |
### Адаптивный размер окна
Пересчёт в τ₃:
- Заполненность > 80% → увеличение размера окна
- Заполненность < 20% уменьшение размера окна
- Шаг: ±20% за τ
- Диапазон: 1 MB 100 MB
---
## Хранение
### Состояние (Global State)
| Аккаунтов | Размер таблицы |
|-----------|---------------|
| 1M | ~1 GB |
| 10M | ~10 GB |
| 100M | ~100 GB |
### История блоков
| TPS | Архивный (20 лет) | Полный (112 дней) | Pruned | Light |
|-----|-------------------|-------------------|--------|-------|
| 7 | ~3.4 TB | ~42 GB | Account Table | Account Table |
| 100 | ~49 TB | ~600 GB | Account Table | Account Table |
| 1000 | ~486 TB | ~5.9 TB | Account Table | Account Table |
| Тип узла | Содержимое | Лотерея |
|----------|-----------|---------|
| Полный | Скользящее окно 8 × τ + Global State + заголовки | weight × 1 |
| Архивный | Полная история от генезиса | weight × 1 |
| Pruned | Global State + заголовки | Наблюдатель |
| Light | Global State | Наблюдатель |
Узел самостоятельно выбирает тип. Участие в лотерее: полный или архивный узел. Вес определяется только временем непрерывной службы. Тип узла на вес не влияет. Архивный узел добровольная роль. Протокол хранит доказательства (заголовки τ с State Root навсегда). Рынок хранит исторические данные (тела блоков). Консенсус не зависит от архивов.
### Fast Sync (новый узел)
1. Цепочка заголовков τ от генезиса проверка Beacon-цепочки и QC (мегабайты)
2. State Root из последнего τ (покрывает весь Global State)
3. Global State snapshot от пиров: каноническая сериализация всех листьев Merkle-дерева состояния (Account Table + Pending Transfer Table + Cooldown Registry + Expiry Queue). Верификация: пересчёт Merkle root из полученных листьев, сравнение с State Root из заголовка τ₃. `MerkleRoot(snapshot_leaves) == state_root_from_header`
4. Блоки аккаунтов за последние 112 дней (скользящее окно)
5. Узел синхронизирован и готов к участию
Заголовки доказывают цепочку state commitments. Snapshot восстанавливает содержимое состояния через пересчёт Merkle root. Блоки скользящего окна обеспечивают верификацию недавних переходов.
---
## Ключи
```
seed
├── Аккаунт: FN-DSA-512 keypair → account_id = SHA-256("mt-account" || suite_id || account_pubkey)
└── Узел: FN-DSA-512 keypair → node_id = SHA-256("mt-node" || node_pubkey)
```
Один seed порождает два FN-DSA-512 keypair: для аккаунта (подпись блоков) и для узла (подпись чекпоинтов, QC). account_id и node_id выводятся из публичных ключей, верифицируемы без знания seed. Бэкап = seed.
---
## Криптографическая реализация
### Primitive layer
Собственная реализация криптографических примитивов запрещена. Только audited библиотеки с constant-time гарантиями и опубликованными test vectors.
| Примитив | Стандарт | Роль |
|----------|----------|------|
| SHA-256 | FIPS 180-4 | Beacon VDF, Service VDF, адреса, Merkle-деревья |
| FN-DSA-512 | Selected NIST candidate, forthcoming FIPS 206 | Подписи блоков аккаунтов |
### Consensus encoding layer
Консенсусно-критическая поверхность: каноническая сериализация, Merkle layout и domain separation. Разная сериализация одного объекта = разный хэш = форк. Требования:
- Fixed binary encoding для каждого консенсусного объекта
- Length-prefix кодирование полей, фиксированный endianness (little-endian)
- Domain separation для всех хэшей:
| Домен | Контекст |
|-------|----------|
| `mt-block` | Хэширование блоков аккаунтов |
| `mt-header` | Хэширование proposal headers |
| `mt-account` | Деривация account_id |
| `mt-pending` | Хэширование pending entries |
| `mt-merkle-leaf` | Листья Merkle-деревьев |
| `mt-merkle-node` | Внутренние узлы Merkle-деревьев |
| `mt-checkpoint` | Хэширование чекпоинтов |
| `mt-beacon` | Beacon VDF seed |
| `mt-service` | Service VDF seed |
| `mt-equivocation` | Хэширование equivocation proofs |
- Альтернативные сериализации запрещены
- Test vectors для каждого консенсусного объекта
- Cross-implementation conformance tests перед запуском mainnet
### Protocol layer
Собственная реализация поверх криптографического ядра:
| Компонент | Назначение |
|-----------|------------|
| Merkle-деревья | State Root, blocks_root, IC proofs (из SHA-256 вызовов) |
| VDF scheduling | Управление Beacon и Service цепочками |
| State machine | Account Table, Pending Transfers, state transitions |
| P2P gossip | Распространение блоков и чекпоинтов |
### Инфраструктура
| Библиотека | Назначение |
|------------|------------|
| RocksDB | Хранение Account Table и блоков |
| libp2p | P2P транспорт |
Production: Rust.
---
## Архитектура
```
┌─────────────────────────────────┐
│ Wallet │
│ Кошелёк, баланс, переводы │
│ FN-DSA-512 keypair │
└──────────────┬──────────────────┘
┌──────────────┴──────────────────┐
│ TimeChain │
│ │
│ Beacon ──→ Service ──→ Execution
│ (часы) (служба) (состояние)
│ │
│ Account Chain (Block Lattice) │
│ Account Table, IC, QC │
│ SHA-256, FN-DSA-512 │
└─────────────────────────────────┘
```