Bits

A representação compacta do alvo no cabeçalho do bloco

Diagrama mostrando o alvo sendo armazenado no campo bits de um cabeçalho de bloco.

O campo bits contém uma representação compacta do alvo (target).

Ele indica o valor que o hash do bloco precisa ficar abaixo para o bloco ser minerado, e precisa representar o valor de alvo correto para a altura do bloco na blockchain.

Target Bits

Converta entre um alvo (target) e sua representação compacta bits.

0x
0 bytes 0 bytes

Estrutura

Como o campo bits representa o alvo?

Diagrama mostrando o expoente e o coeficiente do campo bits e como eles convertem para um valor de alvo completo de 32 bytes.

O campo bits tem duas partes:

  1. Expoente (Primeiro Byte): indica "quão para cima" o coeficiente está.
  2. Coeficiente (3 Bytes Seguintes): contém alguma precisão do valor de alvo completo.

Convertendo

Como converter entre alvo e bits?

Bits para Alvo

Para converter bits em um alvo, você desloca o coeficiente o número de bytes especificado para a esquerda, conforme indicado pelo expoente.

Por exemplo:

Bits: 1705dd01

                          coeficiente (05dd01)
                          ------
Alvo: 00000000000000000005dd010000000000000000000000000000000000000000
                          <---------------------------------------------
                          expoente (0x17 = 23 bytes)
Código
# bits
exponent = 0x17
coefficient = 0x05dd01

# alvo
target = coefficient * 2**(8 * (exponent - 3))
# 2**            = usando uma potência de dois para o deslocamento de bits
# (8 *           = há 8 bits em um byte
# (exponent - 3) = deixa espaço para o coeficiente preencher

# alvo (hex)
target_hex = target.to_s(16)

puts target_hex #=> 5dd010000000000000000000000000000000000000000

Alvo para Bits

Converter um alvo em um campo bits é o inverso da conversão de bits para alvo. Você pega os 3 primeiros bytes significativos do alvo e calcula quantos bytes eles estão deslocados para a esquerda.

Por exemplo:

                          coeficiente (05ae3af)
                          ------
Alvo: 00000000000000000005ae3af5b1628dc0000000000000000000000000000000
                          <---------------------------------------------
                          expoente (0x17 = 23 bytes)

Bits: 1705ae3a

Não esqueça que você está procurando o primeiro byte significativo para o coeficiente. É por isso que o primeiro byte significativo é 05 e não 5a, pois o 5 e o a pertencem a dois bytes diferentes.

O primeiro byte significativo do coeficiente precisa estar abaixo de 80. Se não estiver, você tem que pegar o 00 anterior como primeiro byte.

Isso porque o Bitcoin usa uma codificação personalizada para valores uint256; se o bit 00800000 estiver setado, ele indica um valor negativo. Então, se esse coeficiente for maior que 007fffff, ele estará indicando um valor negativo, e o alvo não pode ser negativo.

Por exemplo, o alvo completo do bloco 489.888 era:

Alvo: 000000000000000000eb304f6a76a77000000000000000000000000000000000

Porém, o primeiro byte significativo é eb. Ele é maior que 7f, então precisamos usar o byte 00 antes dele para impedir que o coeficiente indique um número negativo:

                        coeficiente
                        ------
Alvo: 000000000000000000eb30000000000000000000000000000000000000000000
                        <-----------------------------------------------
                        expoente (0x18 = 24 bytes)

Coeficiente: 00eb30
Expoente: 18

Bits: 1800eb30

Se não fosse por essa codificação personalizada de uint256, o campo bits teria sido 17eb304f.

É por isso que alguns campos bits têm um coeficiente que começa com 00.

Veja aqui: Why 1D00FFFF and not 1CFFFFFF as target in genesis block

De qualquer forma, essa conversão de alvo para bits é o que os mineradores fazem ao criar um campo bits para o cabeçalho do bloco depois de um recálculo do alvo.

Ícone Ferramenta Ajuste do Alvo

Ajuste de Dificuldade

Calcule o novo alvo a partir do alvo atual e do tempo real de mineração de um período de 2016 blocos.

0x
0 bytes
Tempo (segundos)
0d
0d

O período de ajuste de dificuldade é de 2016 blocos. Em média, um bloco é minerado a cada 600 segundos (10 minutos), então o tempo esperado é 2016 × 600 = 1.209.600 segundos.

Razão

O tempo real dividido pelo tempo esperado. Multiplicamos o alvo atual por essa razão para obter o novo alvo.

0x
0x
0 bytes

do cabeçalho do bloco, e é esse o alvo de fato usado na mineração.>Nota: esse valor de alvo é levemente truncado para ser armazenado no campo

Você perde um pouco de precisão ao converter o alvo para bits. Porém, os números são tão grandes que isso não importa muito, então não há necessidade de armazenar a precisão absoluta do alvo no cabeçalho do bloco.

A representação "bits" do alvo é o valor real abaixo do qual os mineradores precisam ficar para minerar um bloco.

Benefícios

Por que convertemos o alvo para bits?

O campo bits economiza espaço no cabeçalho do bloco.

Então, em vez de armazenar o alvo completo de 32 bytes, armazenamos uma representação compacta de 4 bytes.

Propósito

Por que o cabeçalho do bloco contém o alvo?

Há duas funções principais para o campo bits:

  1. É útil para descobrir rapidamente qual era o alvo do bloco.
  2. É o nível real de precisão que o hash do bloco precisa ficar abaixo para o bloco ser minerado. Então, mesmo que o valor completo do alvo após um recálculo tenha mais precisão, é a precisão do campo bits que o hash do bloco precisa ficar abaixo.

Por exemplo, durante o recálculo do alvo no bloco 40.320, este teria sido o alvo completo:

Alvo: 00000000654657a76a76a8000000000000000000000000000000000000000000

Mas o alvo real que um minerador precisa ficar abaixo é a quantidade de precisão que pode ser armazenada no campo bits, que é:

Alvo: 0000000065465700000000000000000000000000000000000000000000000000

Mas, como eu disse, essa perda de precisão aqui não é grande coisa. Nunca vi um bloco minerado com um hash abaixo do alvo truncado, mas acima do cálculo original do alvo.

Terminologia

Por que se chama "bits"?

Não sei por que o campo se chama "bits". O Satoshi nunca explicou a razão por trás da escolha do nome deste campo.

É um nome meio estranho, porque um "bit" é a palavra usada para a menor unidade de dados (ou seja, 8 bits em um byte), o que é um pouco confuso.

Talvez seja porque estavam armazenando alguns bits do alvo (e não a precisão completa), então "bits" foi um nome rápido e fácil para o campo. Quer dizer, todos nós usamos nomes rápidos de variáveis no meio da programação, e eles nem sempre acabam sendo perfeitos.

Recursos