Artigo original: How Bitcoin mining really works

Escrito por: Subhan Nadeem

À medida que o Bitcoin é amplamente adotado e reconhecido, seu modelo de segurança fundamental, conhecido como mineração, é posto sob os holofotes e examinado mais e mais a cada dia.

As pessoas estão cada vez mais preocupadas com o impacto ambiental da mineração de Bitcoin e interessadas no assunto, na segurança e no grau de descentralização do seu modelo subjacente e até no impacto potencial de uma descoberta da computação quântica no futuro dos Bitcoins e de outras criptomoedas.

Muitas vezes, a prova de trabalho é descrita como um "quebra-cabeças criptográfico", mas o que é de fato este quebra-cabeças?

Para compreender de fato essas questões (e quaisquer respostas possíveis), é preciso entender a mineração de Bitcoin em si e da sua evolução.

Este artigo tratará de todos os componentes técnicos e elementos da prova de trabalho e de como eles se mantém em perfeita sincronia, fazendo com que o Bitcoin seja a plataforma descentralizada que é hoje.

Por que a mineração funciona: hashing criptográfico unidirecional

A blockchain do Bitcoin é frequentemente descrita como um banco de dados que é criptograficamente seguro e, subsequentemente, imutável. A tecnologia que alimenta essa imutabilidade e segurança é o hashing criptográfico.

Uma função de hash criptográfico é uma função matemática que, de maneira simples, pega qualquer dado inserido e o converte para uma sequência de caracteres de tamanho fixo.

No entanto, existem quatro características especiais dessas funções que as tornam inestimáveis para a rede dos Bitcoins. São elas:

  1. Determinística para qualquer entrada na função hash criptográfica, a saída resultante será sempre a mesma;
  2. Rápida computar a saída da função hash, dada qualquer entrada, é um processo relativamente rápido (não precisa de computação pesada);
  3. Exclusividadecada entrada na função deve resultar em uma saída completamente aleatória e exclusiva (em outras palavras, não há duas entradas que resultem na mesma saída);
  4. Irreversívela partir de uma saída de uma função hash, a entrada original não pode ser obtida.

Essas regras formam a base que permite à mineração de Bitcoins proteger a rede.

O criador do protocolo Bitcoin, Satoshi Nakomoto, escolheu usar em particular a função hash SHA-256 como base para a mineração de Bitcoins. Essa é uma função de hash criptográfico específica, que foi comprovada matematicamente para atender às propriedades acima. Ela produz sempre um número de 256 bits (a unidade mais básica de computação), que é normalmente representado no sistema numérico hexadecimal com 64 caracteres para facilitar a leitura humana.

A saída da função SHA-256 é normalmente referida como o hash da sua entrada.

1iObT23KZMg-OPHVKyPW3Fp-12cFhc2oaMdI
Uma entrada para uma função hash resulta numa saída totalmente única

Abaixo, temos um exemplo de entrada e saída de uma função SHA-256 (você mesmo pode experimentá-la aqui):

Entrada do SHA-256:
<Transação de Bitcoins>
Saída do SHA-256:
77077b1f4c3ad44c83dc0bdb8d937e9b71c0ef07a35c2664bb7da85be738eacf

Curiosamente, na maioria dos lugares onde o hashing é usado no protocolo Bitcoin, o hashing duplo é usado. Isso significa que a saída original da função SHA-256 é então colocada de volta na função SHA-256 para obter outra saída. Segue abaixo como seria esse processo:

Entrada do SHA-256 (primeiro passo):
<Transação de Bitcoins>
Saída (primeiro passo):
77077b1f4c3ad44c83dc0bdb8d937e9b71c0ef07a35c2664bb7da85be738eacf

Entrada do SHA-256 (segundo passo):
77077b1f4c3ad44c83dc0bdb8d937e9b71c0ef07a35c2664bb7da85be738eacf
Saída (segundo passo e resultado final):
3c6c55b0e4b607b672b50f04e028a6951aed6dc97b91e103fb0f348c3f1dfa00

O hashing duplo é utilizado para proteção contra ataques de aniversário. Um ataque de aniversário é um cenário em que o agressor é capaz de produzir o mesmo hash que outra entrada, só que usando uma entrada completamente diferente (chamada de colisão). Isso quebra a terceira propriedade, da exclusividade. Sem ela, dois blocos de Bitcoin completamente diferentes podem ser representados exatamente pelo mesmo hash, permitindo que os agressores troquem os blocos.

Com a função SHA-256, a probabilidade de esse ataque acontecer é infinitamente pequena. Se não fosse quase impossível, o SHA-256 seria considerado quebrado.

Contudo, outras funções de hash foram "quebradas" no passado. Para evitar que isso aconteça com o SHA-256 no futuro (e efetivamente quebrar o modelo de segurança do Bitcoin) é melhor fazer o hash do hash. Isso reduz pela metade a probabilidade de ocorrer uma colisão, tornando o protocolo muito mais seguro.

De maneira simplificada, a mineração de Bitcoin é um sistema no qual todas as transações de Bitcoin são enviadas para os mineradores de Bitcoin. Os mineradores selecionam transações no valor de um megabyte, agrupam-nas como entrada na função SHA-256 e tentam encontrar um resultado específico que a rede aceite. O primeiro minerador a encontrar esse resultado e publicar o bloco na rede recebe uma recompensa na forma de taxas de transação e criação de novos Bitcoins.

Vamos dar um passo adiante e mergulhar na própria blockchain do Bitcoin para ver o que exatamente os mineradores fazem para tornar a rede segura.

Mineração de bitcoins: uma introdução técnica

A mineração foi introduzida como a solução para o problema do gasto duplo. Se eu tiver 1 Bitcoin e enviá-lo para Bob e depois tentar enviar o mesmo Bitcoin para Alice, a rede garante que apenas uma transação será aceita. Isso é feito pelo processo de mineração.

Antes de mergulhar nos detalhes técnicos, é importante entender por que a mineração é necessária para proteger a rede. A moeda fiduciária que existe atualmente é criada e validada por um banco central. Como o Bitcoin opera sob a rígida premissa de descentralização e consenso, não pode haver nenhuma autoridade central que valide e marque a emissão dessa moeda, bem como a validação de quaisquer transações que ocorram com essa moeda.

Satoshi Nakamoto propôs a única solução conhecida na época para resolver esse problema de validação na forma de um sistema orientado por consenso. Intitulado no whitepaper do Bitcoin como proof-of-work (prova de trabalho), esse esquema justifica de modo elegante que as transações são validadas por aqueles que estão dispostos a gastar energia física computacional e tempo suficientes para fazê-lo, ao mesmo tempo em que introduz um incentivo para induzir a concorrência no mercado. Essa concorrência permite que a descentralização surja e prospere organicamente no ecossistema.

Uma olhada dentro do bloco

Um bloco de Bitcoin consiste basicamente em dois componentes:

1. Transações, na forma de uma árvore de Merkle

Os computadores de mineração coletam transações suficientes para preencher um bloco e as agrupam em uma árvore de Merkle.

Uma árvore de Merkle é um conceito relativamente simples: as transações ficam na parte inferior da árvore como folhas e são criptografadas em um hash usando a função SHA-256. A combinação de duas transações de folha é criptografada novamente em um hash usando a função SHA-256 para formar um pai dessas folhas. Esse pai é continuamente criptografado em hash para cima, combinado com outros pais, até que uma única raiz seja criada. O hash dessa raiz é efetivamente uma representação única das transações que estão abaixo dela.

3Y5SmuCwRz8GnPlpMVo9SUG0n3mg95o4fwoP
Uma visualização de como uma árvore de Merkle é construída - as folhas na parte inferior da árvore são transações

A raiz da árvore de Merkle é uma combinação dos hashes de cada transação na árvore.

Lembre-se que, para qualquer entrada em uma função de hash, a saída é totalmente exclusiva. Portanto, quando a maioria dos nós da rede recebe um bloco minerado, o hash da raiz da árvore de Merkle atua como um resumo imutável de todas as transações nesse determinado bloco.

Se alguém mal-intencionado tentasse alterar o conteúdo de uma transação em um bloco, seu hash seria alterado. Essa alteração de um hash seria propagada pela árvore de Merkle da transação até que o hash da raiz fosse alterado. Qualquer nó pode então detectar rapidamente esse ato malicioso comparando a raiz da árvore de Merkle do bloco alterado com a árvore de Merkle de um bloco válido.

2. O cabeçalho do bloco

O cabeçalho do bloco é um resumo do conteúdo do próprio bloco. Ele contém os seis componentes a seguir:

  • A versão do software que o cliente Bitcoin está executando;
  • O registro de data e hora do bloco;
  • A raiz da árvore de Merkle com as transações contidas;
  • O hash do bloco anterior;
  • Um nonce (número aleatório que pode ser usado apenas uma vez);
  • O target ou destino.

Lembre-se de que a raiz da árvore de Merkle de transações funciona como um resumo eficaz de cada transação no bloco, sem a necessidade de examinar cada transação.

O hash do bloco anterior permite que a rede coloque corretamente o bloco em ordem cronológica. É daí que deriva o termo blockchain - cada bloco é encadeado a um bloco anterior.

O nonce e o target fazem a mineração funcionar. Eles são a base para resolver o quebra-cabeça SHA-256 que os mineradores precisam resolver.

Observe que todos esses dados no cabeçalho do bloco são compactados em 80 bytes usando uma notação chamada little-endian, o que torna a transferência de cabeçalhos de bloco entre os nós um processo trivialmente eficiente. Para essa explicação, ignoraremos essa compactação e assumiremos que os dados estão em sua forma original.

Explicando o problema da mineração

O target armazenado no cabeçalho do bloco é simplesmente um valor numérico armazenado em bits. Na notação tradicional de base 10, esse target varia de 0 a algum lugar na faixa de 2²²⁴ (um número com mais de 67 dígitos), dependendo de quantos mineradores estão competindo para resolver esse problema ao mesmo tempo.

Lembre-se de que o resultado do SHA-256 é apenas um número. O objetivo de um minerador é pegar o cabeçalho do bloco atual, adicionar um número aleatório a ele chamado nonce e calcular seu hash. Esse valor numérico do hash deve ser menor que o valor do target.

Isso é tudo o que há para fazer, mas é muito mais fácil falar do que fazer.

Lembre-se da primeira propriedade do SHA-256: uma entrada em uma função de hash sempre resultará na mesma saída. Portanto, se o minerador pegasse o cabeçalho do bloco, fizesse o hash e percebesse que o valor do hash não era menor do que a meta, ele teria que alterar a entrada de algum modo para tentar encontrar um hash abaixo do valor do target.

É aí que entra o nonce.

O minerador adiciona um número (a partir de 0), chamado nonce, ao cabeçalho do bloco e faz o hash desse valor. Se o valor do hash não for menor do que o target, o minerador incrementará o nonce em 1, o adicionará novamente ao cabeçalho do bloco e fará o hash desse valor alterado. Esse processo é repetido continuamente até que seja encontrado um hash menor que o valor do target.

Um exemplo de mineração

Aqui está uma aproximação grosseira do que compõe o cabeçalho do primeiro bloco:

  • A raiz de Merkle da transação no bloco Genesis:
Raiz de Merkle:
4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
  • A primeira versão conhecida do Bitcoin: 0.1.0
  • O registro de data e hora do bloco: 2009–01–03 18:15:05
  • O target (esse também é o valor mais alto que o target poderá atingir):
Target:
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  • Nenhum hash de bloco anterior – esse foi o primeiro bloco e, portanto, esse é um caso único

O cabeçalho final do bloco após a adição de seus componentes:

RgFYX1FSetNk-EJF91HSNTcVhqIYyDziZJkD
Os dados do bloco Genesis (isso inclui o nonce, mas vamos fingir que não), fonte: bitcointalk

Vamos pegar esse grande cabeçalho e calcular o hash duplo:

SHA-256 do cabeçalho:
7d80bd12dfdccbdde2c41c9f406edfc05afb3320f5affc4f510b05a3394e1c91

SHA-256 do resultado anterior (resultado final):
c5aa3150f61b752c8fb39525f911981e2f9982c8b9bc907c73914585ad2ef12b

Tanto o hash de destino quanto o de saída são números incrivelmente grandes quando convertidos para a base 10 (lembre-se: mais de 67 dígitos). Em vez de tentar demonstrar a comparação dos dois aqui, a função Python a seguir trata da comparação:

def isBlockHashLessThanTarget(blockHash, target):
    return int(blockHash, 16) < int(target, 16)

Será retornado verdadeiro se o hash for menor do que o destino; caso contrário, falso.

Aqui está o resultado do nosso target e do hash de bloco:

mI97AvtxoLFh08Qy99YmpOesirwiyS3a6iLj

Agora, pegamos o valor hexadecimal do bloco original e adicionamos 1 a ele. O resultado é o seguinte:

M7hXm9TXd9CFp3vmZ4sOUHxyvuzMHowjTifh
Observe como o último dígito agora é 1, devido à adição do nonce

Em seguida, executamos o mesmo algoritmo de hashing e a comparação com esses dados alterados. Se não estiverem abaixo do target, continue repetindo.

Quando um hash bem-sucedido é encontrado, o último nonce usado para encontrar essa solução é salvo no bloco.

O nonce listado no bloco Genesis é 2.083.236.893.

Isso significa que Satoshi Nakomoto iterou esse processo mais de 2 bilhões de vezes antes de encontrar o hash correto.

Escrevi uma pequena implementação em Python desse processo de mineração de blocos do Genesis, que pode ser encontrada no meu GitHub.

Veja quanto tempo levaria para você minerar com sucesso o bloco Genesis!

Uma advertência: extraNonce

O valor do nonce em um cabeçalho de bloco é armazenado como um número de 32 bits. Isso significa que o nonce mais alto que alguém pode obter é 2³² (aproximadamente 4 bilhões). Após 4 bilhões de iterações, o nonce se esgota e, se não for encontrada uma solução, os mineradores ficam empacados mais uma vez.

A solução para isso é adicionar um campo à coinbase (o conteúdo da transação de um bloco, armazenado como a árvore de Merkle) chamado extraNonce. O tamanho desse extraNonce é limitado apenas pelo tamanho do próprio bloco e, portanto, pode ser tão grande quanto os mineradores desejarem, desde que o tamanho do bloco esteja dentro dos limites do protocolo.

Se todos os 4 bilhões de valores possíveis do nonce forem esgotados, o extraNonce será adicionado e incrementado na coinbase. Uma nova raiz da árvore de Merkle e, subsequentemente, um novo cabeçalho de bloco são calculados, e o nonce é iterado mais uma vez. Esse processo é repetido até que um hash adequado seja encontrado.

É melhor evitar adicionar o extraNonce até que o nonce se esgote, pois qualquer alteração no extraNonce altera a árvore de Merkle. Isso requer computação adicional para propagar a alteração para cima até que uma nova raiz da árvore de Merkle seja calculada.

A recompensa do minerador

O minerador que conseguir publicar um bloco mais rápido é recompensado com um Bitcoin novinho em folha, criado do nada. Atualmente, essa recompensa é de 12,5 BTC. Como esses Bitcoins surgem?

Cada minerador simplesmente adiciona uma nova transação de saída ao seu bloco que atribui 12,5 Bitcoins a si mesmo antes de começar a minerar o bloco. O protocolo da rede aceitará essa transação especial como válida ao receber um bloco recém-validado. Essa transação especial é chamada de transação de geração.

É responsabilidade do minerador adicionar essa transação ao bloco antes de minerá-lo. Houve, pelo menos, um caso em que os mineradores se esqueceram de adicionar a recompensa à transação antes de minerar um bloco, literalmente destruindo 12,5 BTC!

Validando a prova de trabalho

Digamos que nosso minerador tenha encontrado um hash que seja menor que o target. Tudo o que esse minerador precisa fazer é publicar o bloco minerado com os seis componentes originais em qualquer nó conectado.

Esse nó que recebe o bloco verificará primeiro o conjunto de transações, garantindo que todas as transações sejam válidas (por exemplo, todas as transações estão devidamente assinadas e as moedas não estão sendo gastas duas vezes e/ou criadas do nada).

Em seguida, ele apenas gerará o duplo hash do cabeçalho do bloco e garantirá que o valor esteja abaixo do valor do target incluído no bloco. Quando o bloco for considerado válido, o novo nó continuará a propagar esse bloco pela rede até que todos os nós tenham um registro atualizado.

Como você pode ver, os blocos recém-publicados podem ser facilmente verificados por qualquer nó. Entretanto, a publicação de um bloco válido na rede requer uma quantidade incrivelmente grande de poder computacional (portanto, eletricidade e tempo). Essa assimetria é o que permite que a rede seja protegida e, ao mesmo tempo, permite que os indivíduos que desejam realizar atividades econômicas na rede o façam de maneira relativamente simples.

O tempo de produção de blocos e o ajuste do target

Quando os primeiros mineradores começaram a minerar, cada um deles monitorou o tempo de produção de blocos. Cada bloco de Bitcoin tem um tempo de produção de blocos definido de 10 minutos. Isso significa que, dado o nível atual de capacidade computacional na rede (hashrate da rede), os nós sempre esperam que novos blocos validados sejam produzidos a cada 10 minutos, em média.

É razoável esperar que os blocos sejam produzidos em 10 minutos porque a probabilidade de encontrar um bloco, considerando o hashrate da rede, é conhecida.

Por exemplo, vamos pegar o alvo mais fácil que já existiu no Bitcoin: o bloco de Genesis. A probabilidade de um único hash ser menor do que o target mais fácil é de 1 em 2³². Isso é um em mais de quatro bilhões. Portanto, é razoável esperar que alguém execute 2³² iterações do problema de mineração para encontrar um hash adequado. Os nós da rede esperavam que quatro bilhões dessas iterações fossem executadas por todos os mineradores da rede a cada 10 minutos.

Se, em uma amostra grande de blocos, os blocos começarem a aparecer mais rápido do que 10 minutos, essa é uma indicação bastante clara de que os nós da rede estão iterando por quatro bilhões de hashes muito mais rápido do que 10 minutos. Essa situação faz com que cada nó ajuste o target proporcionalmente com base no aumento (ou diminuição) da potência da rede para garantir que os blocos continuem sendo produzidos a cada 10 minutos.

Na realidade, os nós da rede monitoram o tempo de produção de blocos em 2016 blocos, o que equivale a exatamente duas semanas. A cada duas semanas, o tempo total de produção de blocos é comparado com o tempo de produção de blocos esperado (que é de 20160 minutos).

Para obter o novo target, basta multiplicar o target existente pela proporção do tempo total de produção de blocos real nas últimas duas semanas para obter o tempo de produção de blocos esperado. Isso ajustará o target proporcionalmente à quantidade de poder computacional que entra ou sai da rede.

M3-52KmmkeyZCRECDfzfdACTrILXpveYlDn5
Fórmula para calcular o novo target, executada a cada 20160 minutos (duas semanas) por cada nó de Bitcoin

O tempo de produção de blocos e a capacidade de calcular facilmente a probabilidade de encontrar um bloco válido permitem que os nós monitorem e determinem facilmente o hashpower total na rede e ajustem a rede. Independentemente da quantidade de potência de computacional adicionada à rede ou da rapidez com que é adicionada, em média, o tempo de produção de blocos sempre permanecerá em 10 minutos.

A taxa de hash total atual na rede é de 28,27 exahash por segundo. Isso significa que 28,27 x 10¹⁸ hashes são executados a cada segundo em todos os computadores da rede.

d9dUC5kBAfoDhYFAhuUIF-49pjPT-risoGxB

Resumindo

Aqui, cobrimos de maneira abrangente o seguinte:

  • Por que o hashing criptográfico unidirecional é vital para a prova de trabalho;
  • Um detalhamento da construção de um bloco de Bitcoin;
  • O processo de mineração real e a iteração em si;
  • Como os nós podem validar facilmente outros blocos;
  • Como a rede consegue manter o algoritmo e a competitividade monitorando o tempo de bloqueio e ajustando o target.

Agora, você deve ser capaz de entender e explicar como a prova de trabalho realmente funciona e por que ela é considerada um algoritmo totalmente seguro que permite a descentralização e o consenso!

Siga o autor no Twitter e no Medium se estiver interessado em artigos mais detalhados e informativos como esses no futuro!