Bloco
Um contêiner para transações
Um bloco é um contêiner para transações.
No topo de todo bloco há um cabeçalho de bloco, que resume todos os dados do bloco. Ele contém uma impressão digital (raiz de Merkle) de todas as transações do bloco, além de uma referência a um bloco anterior.
Os mineradores fazem o hash desse cabeçalho repetidamente para tentar obter um resultado abaixo do alvo atual. Se você conseguir um hash de bloco abaixo do alvo, o bloco pode ser adicionado à blockchain. Esse processo é chamado de mineração.
Blocos recém-minerados são enviados entre os nós da rede bitcoin e armazenados permanentemente em disco como parte da blockchain.
Os nós coletam novas transações em um bloco, fazem o hash delas em uma árvore de hash e percorrem valores de nonce para fazer o hash do bloco satisfazer os requisitos de prova de trabalho. Quando resolvem a prova de trabalho, transmitem o bloco para todos e o bloco é adicionado à cadeia de blocos.
Exemplo
A seguir estão os dados brutos do bloco 1 (o primeiro bloco após o bloco gênese).
Eu os separei e destaquei os campos individuais:
01000000 <- versão
6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 <- bloco anterior
982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e <- raiz de merkle
61bc6649 <- tempo
ffff001d <- bits
01e36299 <- nonce
01 <- contagem de transações
01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000 <- transações
Este bloco só contém uma transação, mas a estrutura básica é a mesma para todo bloco.
Estrutura
| Campo | Tamanho | Formato | Descrição |
|---|---|---|---|
| Versão | 4 bytes | little-endian | O número da versão do bloco. |
| Bloco Anterior | 32 bytes | ordem natural de bytes | O hash de um bloco anterior sobre o qual este bloco se constrói. |
| Raiz de Merkle | 32 bytes | ordem natural de bytes | Uma impressão digital de todas as transações incluídas no bloco. |
| Tempo | 4 bytes | little-endian | O horário atual como um timestamp Unix. |
| Bits | 4 bytes | little-endian | Uma representação compacta do alvo atual. |
| Nonce | 4 bytes | little-endian | |
| Contagem de Transações | compacto | compact size | O número de transações que vêm a seguir no bloco. |
| Transações | variável | dados de transação | Todas as transações brutas incluídas no bloco, concatenadas. |
Nota: As linhas destacadas em cinza fazem parte do cabeçalho do bloco.
Nota: A ordem natural de bytes é, na prática, a mesma coisa que little-endian.
Cabeçalho do Bloco
Todo bloco bruto começa com um cabeçalho de bloco.
O cabeçalho do bloco contém um resumo do conteúdo do bloco e é usado para criar o hash do bloco. Tem 80 bytes e seis campos:
Versão
- Tamanho: 4 bytes
- Tipo: inteiro com sinal / bit field
- Formato: little-endian
- Exemplo:
01000000(ou seja, 0x00000001 em little-endian)
O campo versão é usado para sinalizar atualizações do Bitcoin.
Originalmente era apenas um inteiro simples que marcava uma atualização na estrutura do bloco após um soft fork, mas agora é usado pelos mineradores como forma de votar em atualizações do software.
Bloco Anterior
- Tamanho: 32 bytes
- Tipo: bytes puros
- Formato: ordem natural de bytes
- Exemplo:
6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000
O campo bloco anterior contém o hash de um bloco existente, sobre o qual o bloco atual se constrói.
Todos os mineradores querem estender a cadeia mais longa de blocos. Isso porque a cadeia mais longa de blocos é o que todos os nós adotam como a blockchain "correta". Então, ao adicionar um bloco à cadeia "correta", o minerador conseguirá coletar a recompensa de bloco se conseguir minerar seu bloco com sucesso.
Se você construísse sobre um bloco mais abaixo na cadeia, seu bloco não faria parte da cadeia mais longa, então você não conseguiria coletar a recompensa de bloco, e seus esforços para minerar o bloco seriam desperdiçados.
Em outras palavras, quando você cria um novo bloco, o campo bloco anterior contém o hash do bloco que está atualmente no topo da blockchain (também chamado de "ponta", ou tip).
- O campo bloco anterior no cabeçalho do bloco é o que conecta os blocos entre si em uma cadeia, daí o termo "block chain" (cadeia de blocos).
- Não há blocos antes do bloco gênese, então seu campo bloco anterior é todo zeros.
Raiz de Merkle
- Tamanho: 32 bytes
- Tipo: bytes puros
- Formato: ordem natural de bytes
- Exemplo:
982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e
Raiz de Merkle
O campo raiz de Merkle contém uma impressão digital de todos os dados de transação do bloco.
Você cria uma raiz de Merkle fazendo o hash de todos os IDs de transação aos pares, em uma estrutura em árvore, até terminar com um único hash no fim. Então a raiz de Merkle é, em última análise, um hash dos dados de transação dentro do bloco.
A raiz de Merkle impede que o conteúdo do bloco seja alterado por outra pessoa. Todos os dados de transação do bloco são "comprometidos" ao cabeçalho via a raiz de Merkle, então, se alguma transação dentro do bloco for modificada depois, a raiz de Merkle não vai mais bater com o conteúdo do bloco (e o bloco será inválido).
Então a raiz de Merkle é como colocar um selo à prova de violação no bloco.
Tempo
- Tamanho: 4 bytes
- Tipo: inteiro sem sinal
- Formato: little-endian
- Exemplo:
61bc6649(ou seja, 0x4966bc61, ou 1231469665)
Unix Time
O campo tempo contém a hora em que o bloco foi construído como um timestamp Unix.
Esse tempo não precisa ser exato; é apenas um indicador aproximado de quando o bloco foi construído pelo minerador. Porém, o tempo no cabeçalho do bloco deve estar dentro de duas horas, para mais ou para menos, em torno do tempo mediano da rede, para os nós aceitarem o bloco como válido.
Então é possível que um bloco mais acima na cadeia tenha um tempo anterior ao de um bloco mais abaixo na cadeia. Mas isso não importa, porque o campo tempo não é crítico para a ordem dos blocos.
Os blocos da blockchain não precisam estar em ordem cronológica com base nos timestamps. É perfeitamente normal encontrar um bloco mais acima na cadeia com um timestamp anterior ao de um bloco mais abaixo na cadeia.
Este campo tempo é indicado usando Unix Time, que é o número de segundos desde 01 de janeiro de 1970.
Bits
- Tamanho: 4 bytes
- Formato: little-endian
- Exemplo:
ffff001d(ou seja,1d00ffffem little-endian)
Target / Bits
O campo bits é uma representação compacta do alvo no momento em que o bloco foi minerado.
Todo bloco precisa ficar abaixo de um valor de alvo específico para ser considerado válido (ou seja, para ser adicionado à blockchain). Mas, em vez de armazenar o valor de alvo completo de 32 bytes no cabeçalho, usamos a codificação compacta de 4 bytes do "bits".
O formato básico do campo bits é:
- Os últimos 3 bytes contêm a precisão aproximada do alvo completo.
- O primeiro byte indica "quantos bytes para a esquerda" esses 3 bytes ficam em um campo completo de 32 bytes.
Não sei por que esse campo se chama "bits". É um nome confuso, já que temos os termos bits para medidas de dados (ou seja, 8 bits em um byte), mas é assim que ele se chama mesmo.
Esta representação compacta do alvo é o valor real abaixo do qual o hash do bloco precisa ficar ao minerar. O alvo completo em si tem mais precisão quando é calculado inicialmente, mas este campo bits compacto, de menor precisão, é o limiar real abaixo do qual o hash do bloco precisa ficar.
Nonce
- Tamanho: 4 bytes
- Tipo: inteiro sem sinal
- Formato: little-endian
- Exemplo:
01e36299
Este campo é a abreviação de "number used once" (número usado uma vez). É basicamente um campo extra no cabeçalho do bloco que você pode incrementar para obter resultados de hash diferentes para o cabeçalho do bloco.
Eu gosto de chamá-lo de "campo de mineração".
Então, quando você está tentando minerar um bloco, em vez de ter que reconstruir o bloco inteiro a cada tentativa, basta incrementar o campo nonce e obter um resultado de hash completamente diferente para o mesmo bloco de transações.
Todo bloco que você vê na blockchain mostra o valor de nonce "mágico" que por acaso produziu um hash de bloco abaixo do alvo da época. Não há habilidade em encontrar o nonce certo; é apenas uma questão de tentar nonces diferentes o mais rápido possível e torcer pela sorte.
- Nem todo bloco terá um valor de nonce "mágico". Na verdade, a maioria dos cabeçalhos de bloco não produzirá um hash baixo o suficiente mesmo que você esgote completamente o campo nonce.
- O campo nonce tem apenas 4 bytes de tamanho, então o mesmo bloco pode ter até 4294967295 (
0xffffffff) tentativas de hash antes de o campo nonce se esgotar. Depois disso, o bloco precisa ser reconstruído (ou ao menos o campo tempo atualizado) para criar um cabeçalho de bloco diferente para trabalhar.
Transações
Depois do cabeçalho do bloco temos os dados de transação propriamente ditos. É apenas uma série de transações, uma após a outra.
Contagem de Transações
- Tamanho: variável
- Tipo: compact size
- Exemplo:
01
Compact Size
O primeiro dado após o cabeçalho do bloco é, na verdade, uma contagem de transações, indicando o número de transações que vêm a seguir no bloco. É um campo compact size, então normalmente tem 1 ou 3 bytes (dependendo de quantas transações há no bloco).
Transação Coinbase
A primeira transação do bloco é uma transação especial que cria uma nova moeda pertencente ao criador do bloco.
A primeira transação de todo bloco é a transação coinbase. É uma transação especial que os mineradores colocam dentro do bloco para coletar a recompensa de bloco (subsídio do bloco + taxas de transação).
A principal diferença técnica entre uma transação coinbase e uma transação "comum" é que a coinbase não "gasta" bitcoins existentes. Em vez disso, a entrada de uma transação coinbase é em branco (toda zeros), e o valor da saída é o valor da recompensa de bloco.
Uma transação coinbase é obrigatória para todo bloco. Sem ela, o bloco seria inválido.
Os mineradores costumam colocar assinaturas e mensagens personalizadas no scriptsig da sua transação coinbase. Isso porque uma transação coinbase não precisa destravar moedas existentes, então os mineradores ficam livres para colocar qualquer tipo de dado que quiserem no scriptsig.
Transações Comuns
Após a transação coinbase, temos todas as transações "comuns", concatenadas uma após a outra.
Essas transações são selecionadas do memory pool quando o minerador constrói o bloco. Um minerador pode incluir quantas transações quiser (ou poucas) no bloco (até o limite de tamanho do bloco). Porém, os mineradores são incentivados a incluir o máximo de transações que conseguirem, para maximizar o quanto podem ganhar se forem bem-sucedidos em minerar o bloco.
Os mineradores são responsáveis por verificar que cada transação do seu bloco é válida; caso contrário, o bloco inteiro será considerado inválido e não poderá ser adicionado à blockchain.
Transações pai sempre precisam vir antes das transações filhas em um bloco. Então, se uma transação gasta uma saída, essa saída precisa ter sido criada por uma transação de um bloco anterior ou mais cedo no mesmo bloco.
Hash do Bloco
Hash do Bloco
Um hash de bloco é criado fazendo um SHA256 duplo (double-SHA256) do cabeçalho do bloco. O hash do bloco é um identificador único do bloco, o que traz dois benefícios:
- O hash do bloco pode ser usado para referenciar um bloco anterior sobre o qual construir — é isso que encadeia os blocos.
- O hash do bloco pode ser usado para procurar um bloco em um explorador.
O hash do bloco fica em ordem de bytes invertida ao procurar um bloco em um explorador de blocos.
E, como mencionado, durante o processo de mineração, o hash do bloco precisa ficar abaixo do alvo atual para o bloco ser adicionado à blockchain. É por isso que todos os hashes de bloco começam com uma sequência de zeros.
Peso (Weight)
Qual é o tamanho máximo de um bloco?
Um bloco tem capacidade máxima de 4.000.000 unidades de peso.
- O cabeçalho do bloco tem tamanho fixo de 320 unidades de peso (80 bytes).
- Cada transação tem, então, seu próprio peso, tipicamente em torno de 550-850 unidades de peso cada (mas isso pode variar significativamente).
Localização
Onde você encontra os dados brutos de um bloco?
Se você está rodando um nó Bitcoin Core, os dados brutos da blockchain são armazenados nos arquivos blkXXXXX.dat dentro do diretório blocks/:
Linux: ~/.bitcoin/blocks/
Mac: ~/Library/Application Support/Bitcoin/blocks/
Windows: %APPDATA%\Bitcoin\blocks\ Os blocos são armazenados em bytes brutos, então você precisará usar algo como o comando hexdump para conseguir exibi-los. Este é o bloco gênese, por exemplo:
$ hexdump -C -s 8 -n 285 blk00000.dat
00000008 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000018 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000028 00 00 00 00 3b a3 ed fd 7a 7b 12 b2 7a c7 2c 3e |....;...z{..z.,>|
00000038 67 76 8f 61 7f c8 1b c3 88 8a 51 32 3a 9f b8 aa |gv.a......Q2:...|
00000048 4b 1e 5e 4a 29 ab 5f 49 ff ff 00 1d 1d ac 2b 7c |K.^J).._I......+||
00000058 01 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 |................|
00000068 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000078 00 00 00 00 00 00 ff ff ff ff 4d 04 ff ff 00 1d |..........M.....|
00000088 01 04 45 54 68 65 20 54 69 6d 65 73 20 30 33 2f |..EThe Times 03/|
00000098 4a 61 6e 2f 32 30 30 39 20 43 68 61 6e 63 65 6c |Jan/2009 Chancel|
000000a8 6c 6f 72 20 6f 6e 20 62 72 69 6e 6b 20 6f 66 20 |lor on brink of |
000000b8 73 65 63 6f 6e 64 20 62 61 69 6c 6f 75 74 20 66 |second bailout f|
000000c8 6f 72 20 62 61 6e 6b 73 ff ff ff ff 01 00 f2 05 |or banks........|
000000d8 2a 01 00 00 00 43 41 04 67 8a fd b0 fe 55 48 27 |*....CA.g....UH'|
000000e8 19 67 f1 a6 71 30 b7 10 5c d6 a8 28 e0 39 09 a6 |.g..q0..\..(.9..|
000000f8 79 62 e0 ea 1f 61 de b6 49 f6 bc 3f 4c ef 38 c4 |yb...a..I..?L.8.|
00000108 f3 55 04 e5 1e c1 12 de 5c 38 4d f7 ba 0b 8d 57 |.U......\8M....W|
00000118 8a 4c 70 2b 6b f1 1d 5f ac 00 00 00 00 |.Lp+k.._.....|)
0000125 De forma mais simples, você pode solicitar os mesmos blocos brutos ao seu nó Bitcoin Core local usando comandos bitcoin-cli:
$ bitcoin-cli getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f false
0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000 Como alternativa, você pode receber os blocos mais recentes que foram minerados conectando-se a um nó da rede.