Mineração
O processo de adicionar novos blocos à blockchain
A mineração é o processo de tentar adicionar um novo bloco de transações à blockchain.
É uma competição em toda a rede, onde qualquer nó da rede pode trabalhar para tentar adicionar o próximo bloco à cadeia.
Quando um novo bloco é minerado, ele é transmitido pela rede, onde cada nó independentemente o verifica e o adiciona à sua blockchain.
Depois de adicionar o novo bloco, cada nó minerador reinicia o processo para tentar construir em cima desse novo bloco na cadeia. Como resultado, a blockchain é atualizada regularmente graças a um esforço colaborativo dos nós de toda a rede.
O sistema é projetado para que um novo bloco seja minerado a cada 10 minutos, em média.
Método
Como funciona a mineração?
O processo de mineração começa enchendo um bloco candidato com transações do memory pool do seu nó.
Esse bloco candidato é o que vamos tentar minerar na nossa blockchain (e depois enviar a todos os outros para que possam adicioná-lo à blockchain deles também).
Em seguida, construímos um cabeçalho de bloco para esse bloco candidato. É basicamente um resumo curto de todos os dados do bloco, que inclui uma referência a um bloco existente na blockchain sobre o qual queremos construir.
Cabeçalho do Bloco
Agora estamos prontos para começar a minerar este bloco. Para isso, passamos o cabeçalho do bloco pela função de hash SHA-256 duas vezes (chamada HASH256, abreviando), e torcemos para que o número que ela cospe esteja abaixo do alvo atual.
HASH256
Se o hash do seu cabeçalho de bloco não estiver abaixo do alvo, você pode continuar tentando incrementando o campo nonce no cabeçalho do bloco. Isso permite manter o mesmo cabeçalho básico, mas obter um resultado de hash completamente diferente.
E, com sorte, você pode acabar obtendo um hash de bloco abaixo do alvo atual.
Sincronização
Como os nós atualizam a sua blockchain?
Se um minerador consegue um hash de bloco abaixo do alvo para o seu bloco candidato, ele transmite esse bloco ao restante da rede.
Cada nó então confirma que o cabeçalho do bloco tem hash abaixo do alvo e adiciona esse bloco "minerado" à sua blockchain.
A partir daí, cada nó para de trabalhar no seu próprio bloco candidato, constrói um novo (com transações novas do seu memory pool) e começa a tentar construir em cima desse novo bloco na cadeia.
Como resultado, os mineradores trabalham constantemente de forma independente (mas colaborativa) para estender a blockchain com novos blocos de transações.
Prova de Trabalho
O que significa prova de trabalho?
O processo de mineração é frequentemente chamado de prova de trabalho (proof of work).
O termo "prova de trabalho" se refere ao fato de que é preciso trabalho para obter um hash de bloco abaixo do alvo. E, se você conseguir, qualquer outra pessoa pode verificar que o trabalho foi feito, confirmando que o hash do bloco que você construiu está de fato abaixo do alvo.
Em outras palavras, a função de hash é usada como uma forma de provar que você realizou uma quantidade necessária de "trabalho" no seu bloco.
A prova de trabalho envolve procurar um valor que, ao ser hasheado (por exemplo, com SHA-256), produza um hash que comece com um número de bits zero.
Mineradores
Quem pode minerar blocos?
Qualquer nó pode tentar minerar um bloco, e cada nó tem uma chance de sucesso.
Isso significa que temos uma competição em toda a rede, onde qualquer nó da rede pode ser o que adiciona o próximo lote de transações à blockchain.
Porém, embora qualquer um possa tentar minerar, conseguir fazer cálculos de hash o mais rápido possível melhora suas chances de minerar o próximo bloco com sucesso.
A chance de qualquer pessoa encontrar uma solução a qualquer momento é proporcional ao seu poder de CPU.
Como resultado, mineradores com mais poder de processamento (ou "poder de hash") têm mais probabilidade de minerar um bloco do que os que não conseguem fazer hash tão rápido. Então, mesmo que qualquer um possa minerar, isso favorece quem tem hardware de mineração especializado e acesso a energia barata para alimentar esse hardware.
Mas, ainda assim, nada impede você de minerar se quiser.
Recompensa do Bloco
Qual é o incentivo para minerar?
Se você conseguir minerar um bloco, pode reivindicar uma recompensa de bloco.
Ao construir um bloco candidato, você pode colocar a sua própria transação especial no topo do bloco. Ela é chamada de transação coinbase, e permite enviar a si mesmo uma quantidade fixa de bitcoins que não existiam antes.
Então, se você acabar minerando este bloco, poderá gastar os bitcoins que reivindicou da transação coinbase depois que o bloco atingir 100 blocos de profundidade na cadeia mais longa.
Portanto, essa recompensa de bloco funciona como um incentivo para os mineradores minerarem novos blocos e tentarem continuamente estender a cadeia de blocos mais longa que conhecem.
- Enviar bitcoins que não existiam antes só é permitido na transação coinbase. Isso faz da transação coinbase a fonte de todos os novos bitcoins.
- A presença da recompensa de bloco é o motivo de esse processo ser chamado de "mineração". No entanto, de um ponto de vista técnico, a mineração trata principalmente de adicionar novas transações à blockchain.
Intervalo
Quanto tempo leva para minerar um bloco?
O sistema de mineração é projetado para que um minerador na rede bitcoin minere com sucesso um novo bloco a cada 10 minutos (em média).
O tempo é controlado pelo alvo, que é como uma barra de limbo que o hash de um bloco precisa passar por baixo para que o bloco seja permitido na blockchain.
Ajuste do Alvo
Se os blocos são minerados mais rápido que 10 minutos em média ao longo de um período de duas semanas (ex.: porque mais mineradores entraram na rede), o alvo se ajusta para baixo, de forma que fica mais difícil minerar um bloco, e o tempo médio entre blocos volta a cerca de 10 minutos.
Como resultado, o alvo se ajusta regularmente para tentar manter um intervalo regular de 10 minutos entre os blocos recém-minerados. Isso impõe uma taxa consistente de novos blocos, além de uma emissão consistente de novos bitcoins na rede.
Propósito
Por que usamos mineração?
O sistema de mineração permite que computadores em uma rede resolvam conflitos sem a necessidade de um computador central para resolvê-los.
O Bitcoin roda em uma rede de computadores independentes, então é possível criar duas transações conflitantes (enviando os mesmos bitcoins para lugares diferentes) e inseri-las em nós diferentes da rede ao mesmo tempo. Alguns nós receberão a transação A primeiro, e outros nós receberão a transação B primeiro.
Mas, graças ao mecanismo de mineração, apenas uma dessas transações chegará à blockchain.
Eventualmente, um dos nós da rede minerará um bloco de transações do seu memory pool e transmitirá esse bloco ao restante da rede. Quando os nós recebem esse bloco, eles o adicionam à sua cadeia e removem quaisquer transações conflitantes do seu memory pool.
Como resultado, o processo de mineração funciona como um mecanismo de ordenação de transações em uma rede de computadores; os blocos minerados têm a palavra final sobre quais transações pertencem à blockchain.
Melhor ainda, graças ao fato de que qualquer um pode minerar, nenhum nó isolado da rede jamais está em controle completo sobre quais transações entram na blockchain.
Um único minerador pode controlar quais transações entram na blockchain se conseguir adquirir a maioria do poder de mineração. Isso é conhecido como um ataque de 51%.
Técnico
Como você minera um bloco?
Para minerar um bloco, você começa construindo um cabeçalho de bloco para o seu bloco candidato.
Por exemplo, é assim que o cabeçalho do bloco 100.000 teria começado:
0100000050120119172a610421a6c3011dd330d9df07b63616c2cc1f1cd00200000000006657a9252aacd5c0b2940996ecff952228c3067cc38d4885efb5a4ac4247e9f337221b4d4c86041b00000000 Agora que você tem um cabeçalho de bloco, você tenta "minerá-lo" passando-o pelo HASH256. Você continua incrementando o valor do nonce conforme avança, para tentar obter um resultado abaixo do alvo.
HASH256
Por exemplo:
Nonce Hash256
-------- -------
00000000: 5bd0d617b30a972407ad69a845cd74fb201d940cd45acc15fcd4761493bc3ae2
01000000: 6879c316d8a96269825111bb0616331307bb6677b2af55127922d8c568e4b2db
02000000: 34d69cb489442234ec54462e18262bf1a9c756a4e7909e68edf979a0cb39a3fa
03000000: 8cf5e032093cfcbf4f6b443608631dd33699fca13dcbd6118992f9d451b70dd8
04000000: a32d73e3f2fd0579c44080cb6b1717582d37b8f47a8445922dee0996b503c04c
05000000: 70b11dabc90a107918a55eff7e940d41b0ce1924aeed2f0b7ccb2d4ee60e1617
06000000: b38afc30567703629226557a7748bea449693156e0b116b03a8442ccc3b9005e
07000000: 2a6008f39daa1238388eadcab111c6b556c3d89a46558c98f8ed32746fb5d7b8
08000000: 248e33c82a744786e7e16336612221850e32f8e6cb09b2eb0b0730ac6beb71b4
09000000: a4aea05d2750e49e8f95f5608293f6b4f45bd34aee51e86893dd8c0230d19185
0a000000: ce2225a69a5bf2dbb25cbb27fda78a8c4c3ac5280ec7996426eeefeb0e5e1ecb
... Eventualmente, você pode encontrar um valor de nonce que produz um resultado de hash abaixo do alvo:
Nonce Hash256
-------- -------
0f2b5710: 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506 - O nonce é um campo de 4 bytes em ordem de bytes little-endian.
- O resultado de fazer o hash do cabeçalho de bloco bruto através do HASH256 vai parecer estar de trás para frente à primeira vista. Isso porque os hashes de bloco são exibidos em ordem de bytes invertida nos exploradores de blockchain.
Inverter Bytes
Código
Aqui está um código em Ruby que mostra como você pode minerar um bloco (como o de cima).
O código é mais simples do que você imagina. A única parte complicada é colocar os dados do cabeçalho do bloco no formato correto antes de fazer o hash.
Simulador de Mineração
require 'digest/sha2'
# -----------------
# Utility Functions
# -----------------
# The hash function used in mining (convert hexadecimal to binary first, then SHA256 twice)
def hash256(data)
binary = [data].pack("H*")
hash1 = Digest::SHA256.digest(binary)
hash2 = Digest::SHA256.hexdigest(hash1)
end
# Convert a number to fit inside a field that is a specific number of bytes e.g. field(1, 4) = 00000001
def field(data, size)
hex = data.to_i.to_s(16).rjust(size * 2, '0')
end
# Reverse the order of bytes (often happens when working with raw bitcoin data)
def reversebytes(data)
data.scan(/../).reverse.join
end
# ------------
# Block Header (e.g. block 100,000)
# ------------
# Target (optional)
target = '000000000004864c000000000000000000000000000000000000000000000000'
# Block Header (Fields)
version = '1'
prevblock = '000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250'
merkleroot = 'f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766'
time = '1293623863' # Unixtime (29 Dec 2010, 11:57:43)
bits = '1b04864c'
nonce = 0 # 274148111
# Block Header (Serialized)
header = reversebytes(field(version, 4)) + reversebytes(prevblock) + reversebytes(merkleroot) + reversebytes(field(time, 4)) + reversebytes(bits)
# -----
# Mine!
# -----
loop do
# hash the block header
attempt = header + reversebytes(field(nonce, 4))
result = reversebytes(hash256(attempt))
# show result
puts "#{nonce}: #{result}"
# end if we get a block hash below the target
if result.to_i(16) < target.to_i(16)
break
end
# increment the nonce and try again...
nonce += 1
end Comandos
bitcoin-cli getblocktemplate
Este comando pega transações do memory pool do seu nó e retorna os dados de que você precisa para começar a minerar um novo bloco.
O chato é que você também precisa fornecer um array meio esquisito para especificar o tipo de modelo de bloco que quer (veja a BIP22). É isto que eu costumo usar: bitcoin-cli getblocktemplate '{"rules": ["segwit"]}'
Este comando retorna as informações principais do cabeçalho do bloco, como o bloco anterior, o time e os bits, mas você precisará construir a raiz de Merkle por conta própria.
bitcoin-cli submitblock [hex]
Envia um bloco bruto para a rede.
Por exemplo, este é o bloco gênese:
$ bitcoin-cli submitblock 0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000 Este é um bloco bruto completo. Ele deve incluir o cabeçalho do bloco, a contagem de transações e todos os dados brutos das transações.
bitcoin-cli getmininginfo
Este comando retorna algumas informações interessantes sobre mineração.
Por exemplo:
$ bitcoin-cli getmininginfo
{
"blocks": 953548,
"currentblockweight": 3999726,
"currentblocktx": 2861,
"bits": "1702068f",
"difficulty": 138955357012247.3,
"target": "00000000000000000002068f0000000000000000000000000000000000000000",
"networkhashps": 9.394390828708721e+20,
"pooledtx": 3532,
"chain": "main",
"next": {
"height": 953549,
"bits": "1702068f",
"difficulty": 138955357012247.3,
"target": "00000000000000000002068f0000000000000000000000000000000000000000"
},
"warnings": []
} Se você rodar bitcoin-cli getblocktemplate antes, ele também mostrará quantas transações do memory pool estão sendo incluídas no próximo bloco (em currentblocktx).