Skip to content
Learning Platform
Intermediate
20 minutes
Сложность Корректировка 2016 блоков nBits Target Compact формат

Prerequisites:

  • 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 уменьшается (сложнее), медленнее — увеличивается (легче)
Корректировка сложности Bitcoin
Формула корректировки:
new_target = old_target * (actual_time / expected_time)
expected_time = 2016 * 600с = 1 209 600с (14 дней) | factor: min 0.25x, max 4.0x
14д12дx0.857Эпоха 1^ сложнее15дx1.071Эпоха 2v легче14.1дx1.007Эпоха 3= стабильно7дx0.500Эпоха 4^ сложнее
nBits компактный формат (Genesis block)
nBits0x1d00ffff
Экспонента0x1d = 29
Мантисса0x00ffff
target = 0x00ffff * 2^(8 * (29 - 3)) = 0x00000000FFFF00...0000
Формат: первый байт = экспонента (количество байт в target), остальные 3 байта = мантисса (старшие значащие байты 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—2010CPU/GPU майнингМинимальная сложность, медленный рост
2013Первые ASICВзрывной рост сложности в ~1000x за год
2017Бычий рынокХешрейт вырос с 2 до 15 EH/s
Май 2021Запрет майнинга в КитаеХешрейт упал на ~50%, сложность снизилась
2022ВосстановлениеХешрейт полностью восстановился и продолжил рост
20244-й halving3.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.

Finished the lesson?

Mark it as complete to track your progress