Требуемые знания:
- 06-mining-pow
Сложность и корректировка
Зачем это блокчейну?
Если все майнеры мира вдруг удвоят мощности, блоки будут находиться каждые 5 минут вместо 10. Но через 2016 блоков (~1 неделю вместо 2) сеть автоматически увеличит сложность в 2 раза, восстановив 10-минутный интервал.
Этот механизм — одно из самых элегантных решений Сатоси. Без него Bitcoin не мог бы поддерживать предсказуемую эмиссию и стабильный темп подтверждения транзакций.
# Ядро корректировки сложности -- 4 строки:
expected_time = 2016 * 10 * 60 # 1 209 600 секунд (2 недели)
actual_time = last_block_time - first_block_time
factor = max(0.25, min(4.0, actual_time / expected_time))
new_target = int(old_target * factor)
Алгоритм корректировки
Каждые 2016 блоков (одна «эпоха») сеть пересчитывает target по формуле:
new_target = old_target * (actual_time / expected_time)
Где:
expected_time = 2016 * 600 = 1 209 600секунд (14 дней)actual_time— фактическое время, за которое были намайнены 2016 блоков- Результат: если блоки шли быстрее — target уменьшается (сложнее), медленнее — увеличивается (легче)
Нажмите на эпоху, чтобы увидеть детали расчёта. Обратите внимание:
- Эпоха 1: блоки за 12 дней (слишком быстро) — сложность растёт
- Эпоха 2: блоки за 15 дней (слишком медленно) — сложность снижается
- Эпоха 3: почти идеальные 14 дней — минимальная корректировка
- Эпоха 4: хешрейт удвоился — сложность резко возрастает
Почему 2016 блоков?
2016 блоков * 10 минут = 20 160 минут = 336 часов = 14 дней
Две недели — это компромисс:
- Достаточно длинный период, чтобы сгладить случайные отклонения (время между блоками — случайная величина с экспоненциальным распределением)
- Достаточно короткий, чтобы реагировать на значительные изменения хешрейта
Почему именно 2016? Вероятно, Сатоси выбрал удобное число: 2016 = 2^5 * 63 = 7 * 288 (288 блоков в сутках * 7 дней… почти, если бы неделя, но скорее совпадение).
Предохранительные ограничения
Фактор корректировки ограничен диапазоном 0.25x — 4x:
factor = actual_time / expected_time
factor = max(0.25, min(4.0, factor)) # Ограничение
Это защита от экстремальных ситуаций:
- Если хешрейт упал в 10 раз (блоки за 100 минут): без ограничения target увеличился бы в 10 раз. С ограничением — максимум в 4 раза за эпоху. Через несколько эпох target всё равно адаптируется.
- Если хешрейт вырос в 100 раз: без ограничения target уменьшился бы в 100 раз. С ограничением — максимум в 4 раза за эпоху.
Плавность корректировки предотвращает атаки на основе манипуляции timestamp-ами.
nBits: компактный формат сложности
В заголовке блока target хранится не как полное 256-битное число, а в компактном формате nBits (4 байта).
Формат: экспонента + мантисса
nBits = 0x1d00ffff (Genesis block)
^^------ экспонента = 0x1d = 29
^^^^^^ мантисса = 0x00ffff
Декодирование
target = мантисса * 2^(8 * (экспонента - 3))
target = 0x00ffff * 2^(8 * (29 - 3))
target = 0x00ffff * 2^208
target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
Пример декодирования шаг за шагом
nBits = 0x1d00ffff
# Шаг 1: разделяем на экспоненту и мантиссу
exponent = nBits >> 24 # 0x1d = 29
mantissa = nBits & 0x00FFFFFF # 0x00ffff = 65535
# Шаг 2: вычисляем target
shift = 8 * (exponent - 3) # 8 * 26 = 208 бит
target = mantissa << shift
# Шаг 3: проверяем
print(f"Target: {target:#066x}")
# 0x00000000ffff0000000000000000000000000000000000000000000000000000
Это максимальный target (минимальная сложность). Реальные значения nBits дают гораздо меньший target.
Исторические данные
Сложность Bitcoin прошла через несколько драматических периодов:
| Период | Событие | Влияние на сложность |
|---|---|---|
| 2009—2010 | CPU/GPU майнинг | Минимальная сложность, медленный рост |
| 2013 | Первые ASIC | Взрывной рост сложности в ~1000x за год |
| 2017 | Бычий рынок | Хешрейт вырос с 2 до 15 EH/s |
| Май 2021 | Запрет майнинга в Китае | Хешрейт упал на ~50%, сложность снизилась |
| 2022 | Восстановление | Хешрейт полностью восстановился и продолжил рост |
| 2024 | 4-й halving | 3.125 BTC за блок, хешрейт продолжает расти |
После запрета в Китае (май 2021) произошло самое крупное снижение сложности в истории Bitcoin — около 28% за несколько эпох. Механизм корректировки отработал штатно: через ~3 месяца 10-минутный интервал восстановился.
Алгоритмический уровень
def calculate_new_target(old_target: int, actual_time_seconds: int) -> int:
"""
Корректировка сложности Bitcoin каждые 2016 блоков.
expected_time = 2016 * 10 * 60 = 1 209 600 секунд.
Фактор ограничен диапазоном [0.25, 4.0].
"""
EXPECTED_TIME = 2016 * 10 * 60 # 1 209 600 секунд
# Вычисляем фактор корректировки
adjustment = actual_time_seconds / EXPECTED_TIME
# Ограничиваем фактор
adjustment = max(0.25, min(4.0, adjustment))
# Вычисляем новый target
new_target = int(old_target * adjustment)
# Target не может превышать максимум (минимальная сложность)
MAX_TARGET = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
new_target = min(new_target, MAX_TARGET)
return new_target
# Пример: блоки шли по 8 минут в среднем
actual = 2016 * 8 * 60 # 967 680 секунд (блоки быстрее)
old_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
new_target = calculate_new_target(old_target, actual)
print(f"Фактор: {actual / (2016*600):.4f}") # 0.8000
print(f"Target уменьшился -> сложность выросла")
Математический уровень
Difficulty (числовое значение сложности)
difficulty = max_target / current_target
Где max_target — target Genesis-блока (0x00000000FFFF00…). При difficulty = 1 это самая лёгкая сложность. На 2025 год difficulty составляет порядка 80—100 триллионов.
Связь сложности и хешрейта
hashrate ≈ difficulty * 2^32 / 600
Или наоборот:
difficulty ≈ hashrate * 600 / 2^32
Это следует из того, что за 600 секунд (10 минут) сеть с хешрейтом H делает H * 600 хешей, и вероятность каждого хеша оказаться ниже target = 1/difficulty * (max_target / 2^256).
Распределение времени между блоками
Время между блоками — экспоненциальное распределение с параметром lambda = hashrate * P(hash < target):
P(T > t) = e^(-lambda * t)
Среднее время = 1/lambda ≈ 600 секунд
Медиана = ln(2)/lambda ≈ 416 секунд (блоки чаще приходят раньше среднего)
Поэтому «10 минут» — это среднее, но конкретный блок может быть найден и за 1 секунду, и за 2 часа.
Практика
Реализуйте корректировку сложности в Python, промоделируйте несколько эпох и исследуйте влияние колебаний хешрейта:
Notebook: labs/crypto/notebooks/12-bitcoin-mining.ipynb (раздел Difficulty Adjustment)
Что дальше?
Мы разобрались, как майнеры находят блоки и как сеть поддерживает стабильный темп. Но как новый блок попадает к другим узлам? Как транзакции распространяются по сети до включения в блок? В следующем уроке изучим сетевой протокол Bitcoin P2P.
Закончили урок?
Отметьте его как пройденный, чтобы отслеживать свой прогресс