Alvo (Target)

O número que o hash de um bloco precisa ficar abaixo

Diagrama mostrando o hash de bloco de um bloco candidato tentando ficar abaixo de um valor de alvo.

O alvo (target) é um número que o hash de um bloco candidato precisa ficar igual ou abaixo para que o bloco seja adicionado à blockchain. Ele é usado durante a mineração.

O alvo é ajustado a cada 2016 blocos (aproximadamente a cada duas semanas) para tentar garantir que os blocos sejam minerados a cada 10 minutos em média. Isso cria um tempo consistente entre os blocos e uma emissão consistente de novos bitcoins (via recompensa de bloco).

Para compensar o aumento da velocidade do hardware e o interesse variável em rodar nós ao longo do tempo, a dificuldade da prova de trabalho é determinada por uma média móvel que mira um número médio de blocos por hora. Se eles são gerados rápido demais, a dificuldade aumenta.
Satoshi Nakamoto, Whitepaper do Bitcoin

Período

Quando o alvo se ajusta?

O alvo se ajusta a cada 2016 blocos, que é aproximadamente a cada duas semanas.

Os blocos são minerados a cada 10 minutos (aproximadamente), e há 20.160 minutos em duas semanas (2016 × 10).

Histórico

Aqui estão a altura, o alvo e a variação de cada ajuste de dificuldade na história do Bitcoin (do mais recente para o gênese — role para carregar mais):

Altura Alvo Variação da Dificuldade Data
Carregando…

Ajuste

Como o alvo é calculado?

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

O alvo do primeiro bloco (gênese) foi definido como:

00000000ffff0000000000000000000000000000000000000000000000000000
Diagrama mostrando o alvo do bloco gênese.

Esse valor inicial é fixo no código-fonte de todo nó Bitcoin (chainparams.cpp). É também o valor máximo possível do alvo. Foi provavelmente um palpite do Satoshi sobre um bom ponto de partida para um alvo difícil o suficiente para resultar em um intervalo de 10 minutos.

A cada 2016º bloco, cada nó olha o tempo entre os 2015 blocos anteriores e calcula se eles foram minerados mais rápido ou mais devagar que 10 minutos em média.

Diagrama mostrando o período do alvo entre o bloco gênese e o 2016º bloco, junto com o timestamp de cada bloco.

Se os blocos desse período forem minerados mais rápido que 10 minutos, o alvo é ajustado para baixo, tornando mais difícil ficar abaixo dele no próximo período de blocos.

Diagrama mostrando o valor do alvo sendo ajustado para baixo porque os blocos foram minerados mais rápido que o esperado.

Inversamente, se os blocos forem minerados mais devagar que 10 minutos, o alvo é ajustado para cima, tornando menos difícil ficar abaixo dele no próximo período de blocos.

Diagrama mostrando o valor do alvo sendo ajustado para cima porque os blocos foram minerados mais devagar que o esperado.

Como resultado, cada nó recalcula regularmente o alvo para manter um intervalo médio de 10 minutos conforme os mineradores entram e saem da rede.

Veja o código no fim da página para um exemplo prático.

Sincronização

Como os nós calculam o mesmo alvo?

Todos fazem o mesmo cálculo com os mesmos dados da cadeia, então todos obtêm o mesmo resultado no mesmo elo da cadeia.
Satoshi Nakamoto, Bitcoin P2P e-cash paper

Cada da rede opera de forma independente, então não há uma autoridade central para determinar o valor atual do alvo.

Porém, como os nós sempre adotam a cadeia mais longa de blocos como a sua blockchain, eles calculam o mesmo alvo.

Por exemplo, quando você roda o Bitcoin pela primeira vez, o seu nó faz o download inicial da blockchain (initial block download) e calcula os alvos conforme avança. E, como você está recebendo os mesmos blocos que todos os outros, acaba calculando o mesmo alvo atual ao chegar à ponta da blockchain.

Diagrama mostrando o download inicial da blockchain e os cálculos do alvo.

Além disso, todos os nós atualizam continuamente para a mesma versão da blockchain (pois sempre adotam a cadeia de blocos mais longa disponível). Portanto, os nós também calculam o mesmo valor do alvo a cada novo bloco minerado.

Diagrama mostrando os nós da rede recalculando o alvo quando novos blocos são minerados.

Como resultado, apesar de os nós calcularem o alvo de forma independente, todos chegam ao mesmo alvo porque compartilham a mesma visão da blockchain.

Propósito

Por que o Bitcoin usa um alvo?

O alvo regula a velocidade com que novos blocos são adicionados à blockchain. Isso tem dois benefícios:

1. Dá tempo para os blocos se propagarem pela rede.

Se as transmissões acabarem sendo mais lentas na prática do que o esperado, o tempo-alvo entre blocos talvez precise ser aumentado para evitar desperdício de recursos. Queremos que os blocos normalmente se propaguem em muito menos tempo do que leva para gerá-los, caso contrário os nós passariam tempo demais trabalhando em blocos obsoletos.
Satoshi Nakamoto, Bitcoin P2P e-cash paper

É preferível que os mineradores trabalhem para estender a mesma cadeia de blocos o máximo possível. Para que isso funcione, precisamos dar tempo para que os novos blocos se propaguem pela rede antes do próximo ser minerado.

Diagrama mostrando um bloco recém-minerado se propagando pelos nós da rede.

Se os blocos forem minerados mais rápido do que conseguem ser transmitidos pela rede, os mineradores frequentemente trabalharão em cima de blocos "antigos" da blockchain (porque ainda não tiveram a chance de receber os blocos mais recentes).

Isso fará com que os mineradores construam várias blockchains concorrentes; apenas uma delas se tornará a mais longa, então alguns mineradores acabarão desperdiçando energia construindo em cima de uma cadeia concorrente, só para ela ser deixada para trás por causa de uma reorganização da cadeia.

Diagrama mostrando mineradores trabalhando na construção de duas blockchains diferentes por não receberem os blocos mais recentes rápido o suficiente.

Portanto, esse atraso de tempo (o intervalo entre blocos) permite que os blocos se propaguem pela rede, de modo que mais mineradores possam adotar a cadeia mais longa disponível, o que ajuda a concentrar o poder de mineração da rede na extensão da mesma cadeia de blocos.

Diagrama mostrando mineradores focados em estender a mesma blockchain porque o bloco mais recente teve tempo de se propagar pela rede.

2. Uma emissão consistente de novos bitcoins.

As moedas precisam ser distribuídas inicialmente de alguma forma, e uma taxa constante parece ser a melhor fórmula.
Satoshi Nakamoto, Bitcoin P2P e-cash paper

O Bitcoin é uma moeda, então ter uma taxa fixa de novos bitcoins introduzidos no sistema ajuda a fornecer estabilidade.

Diagrama mostrando as recompensas de bloco sendo emitidas a uma taxa constante.

Então, graças ao alvo, você pode ter confiança de que novos bitcoins serão cunhados a uma taxa previsível.

Localização

Onde você encontra o alvo?

O alvo fica armazenado no campo bits do cabeçalho de cada bloco.

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

O campo bits é uma representação compacta do alvo (para economizar espaço no cabeçalho do bloco). Mas você pode converter facilmente entre a representação bits e o alvo completo.

Target Bits

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

0x
0 bytes 0 bytes

Comandos

bitcoin-cli getblocktemplate

A forma mais simples de obter o alvo atual. Ao solicitar um modelo de bloco (para mineração), ele também retorna o alvo atual.

Este comando retorna muitos dados, então é melhor usar grep para filtrar o alvo.

$ bitcoin-cli getblocktemplate '{"rules": ["segwit"]}' | grep target
"target": "00000000000000000002068f0000000000000000000000000000000000000000",

bitcoin-cli getdifficulty

Alternativamente, você pode pedir a dificuldade atual e convertê-la para o alvo:

$ bitcoin-cli getdifficulty
138955357012247.30
Ícone Ferramenta Dificuldade

Dificuldade

e a dificuldade.>Converta entre um

0x
0x
0 bytes
0d

Converter de dificuldade para alvo nem sempre é preciso. A dificuldade é um número de ponto flutuante calculado a partir da mudança entre o alvo inicial e o atual, então pode perder precisão.

bitcoin-cli getblockheader [hash do bloco]

Este comando permite encontrar um alvo anterior de um bloco específico. O alvo na época da mineração fica armazenado em cada cabeçalho de bloco no formato bits, que você pode converter para o alvo completo.

$ bitcoin-cli getblockheader 000000000000000002e9533a4fe03bb251b3fdb30ffaa384aad133b7fae594cf
{
  "hash": "000000000000000002e9533a4fe03bb251b3fdb30ffaa384aad133b7fae594cf",
  "confirmations": 425677,
  "height": 401184,
  "version": 4,
  "versionHex": "00000004",
  "merkleroot": "b4afa0502a55fdfa4a5cda6ea2bc546ba527d276ea9c7e848b8cd478cd9b6607",
  "time": 1457133956,
  "mediantime": 1457132303,
  "nonce": 3778923481,
  "bits": "1806f0a8",
  "difficulty": 158427203767.3917,
  "chainwork": "00000000000000000000000000000000000000000012da32364c8f47d519604d",
  "nTx": 845,
  "previousblockhash": "000000000000000003c4a4d9c62b3a7f4893afe14eef8a6a377229d23ad4b1ea",
  "nextblockhash": "00000000000000000037ab74c8db9b7a9d7de039210d8eafaeb44ba35adfb624"
}
Ícone Ferramenta Bits do Alvo

Target Bits

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

0x
0 bytes 0 bytes

Você pode obter o alvo do bloco mais recente da cadeia com este one-liner:

$ bitcoin-cli getblockheader $(bitcoin-cli getblockhash $(bitcoin-cli getblockcount))

Código

Aqui está um exemplo de código em Ruby para calcular os ajustes do alvo.

Este código calcula o novo alvo do bloco 403.200, usando os timestamps dos bloco 401.184 e bloco 403.199.

# 403,200 - NEW TARGET
# 403,199              | last block
#		               |
#                      |
#                      |
# 401,184 - NEW TARGET | first block (target = 0x000000000000000006f0a8000000000000000000000000000000000000000000)

# 1. Get the timestamps for the first and last block in the target adjustment period
first = 1457133956 # block 401,184
last  = 1458291885 # block 403,199

# 2. Work out the ratio of the actual time against the expected time
actual = last - first     # 1157929 (number of seconds between first and last block)
expected = 2016 * 10 * 60 # 1209600 (number of seconds expected between 2016 blocks)
ratio = actual.to_f / expected.to_f

# 3. Limit the adjustment by a factor of 4 (to prevent massive changes from one target to the next)
ratio = 0.25 if ratio < 0.25
ratio = 4 if ratio > 4

# 4. Multiply the current target by this ratio to get the new target
current_target = 0x000000000000000006f0a8000000000000000000000000000000000000000000
new_target = (current_target * ratio)

# 5. Don't let the target go above the maximum target
max_target = 0x00000000ffff0000000000000000000000000000000000000000000000000000
new_target = max_target if new_target > max_target

# 5. Truncate the target, because the official target is the truncated "bits" format stored in the block header
# This code is a bit rough, because it's working with strings when I should really be working with actual bytes.
new_target = new_target.to_i.to_s(16) # convert from decimal to hexadecimal
new_target = new_target.size % 2 != 0 ? '0' + new_target : new_target # make sure it's an even number of characters (i.e. bytes)
truncated = new_target.scan(/../).each_with_index.map { |byte, i| byte = i >= 3 ? "00" : byte }.join # set all bytes apart from first 3 to zeros
# e.g. 6a4c316c01f354000000000000000000000000000000000 <- full precision
# e.g. 6a4c3000000000000000000000000000000000000000000 <- official target

# 6. Display the full target (with leading zeros)
target = truncated.rjust(64, '0')
puts target
# 000000000000000006a4c3000000000000000000000000000000000000000000

Erro de "off-by-one". Os ajustes de dificuldade são, na verdade, calculados usando o tempo ao longo de 2015 blocos (ex.: 403199 − 401184 = 2015), e não 2016 como seria de se esperar. Isso foi um erro de implementação no código, e ainda existe hoje.

Alvo oficial. O alvo que os mineradores realmente precisam ficar abaixo ao minerar é o alvo truncado que é armazenado no campo bits. Ou seja, não é o alvo de precisão completa que você obtém após o cálculo de ajuste do alvo.

Perguntas Frequentes

Por que 10 minutos entre os blocos?

Acho que ninguém, exceto o Satoshi, sabe exatamente por que 10 minutos foi escolhido. Meu palpite é que parecia longo o suficiente para permitir que os blocos se propagassem pela rede (minimizando reorganizações da cadeia) e curto o suficiente para não esperar demais pelas novas transações. E 10 é um número redondo agradável.

O que faz os blocos serem minerados mais rápido ou mais devagar que 10 minutos?

Primeiro, a mineração é imprevisível: você nunca sabe quando um minerador vai encontrar o próximo bloco. Segundo (e mais importante), os mineradores podem entrar e sair da rede a qualquer momento, o que afeta a velocidade. Quanto mais mineradores entram, mais hashing acontece, e mais provável é que um novo bloco seja minerado em menos de 10 minutos.

Recursos

Obrigado a David Harding por apontar que é possível obter o alvo diretamente do bitcoind usando bitcoin-cli getblocktemplate.