Bits
A representação compacta do alvo no cabeçalho do 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.
Estrutura
Como o campo bits representa o alvo?
O campo bits tem duas partes:
- Expoente (Primeiro Byte): indica "quão para cima" o coeficiente está.
- 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.
Ajuste do Alvo
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:
- É útil para descobrir rapidamente qual era o alvo do bloco.
- É 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.