Minerador de bitcoin com PYTHON?!
Tags: python, bitcoin, mine, script
Published: 2021-05-24 14:09:25

 * [ Primeiramente, o que é bitcoin?](#primeiramente-o-que-%C3%A9-bitcoin)  
 * [ Como funciona as transações do bitcoin?](#como-funciona-as-transa%C3%A7%C3%B5es-do-bitcoin)  
 * [ Criptografia/SHA-256](#criptografiasha256)  
 * [ Qual a aplicação do SHA-256 no bitcoin?](#qual-a-aplica%C3%A7%C3%A3o-do-sha256-no-bitcoin)  
 * [ Vamos para o código?](#vamos-para-o-c%C3%B3digo)  
 * [ Vamos testar como funciona essa função?](#vamos-testar-como-funciona-essa-fun%C3%A7%C3%A3o)  
 * [ Funções do nosso script!](#fun%C3%A7%C3%B5es-do-nosso-script)  
 * [ Função main!](#fun%C3%A7%C3%A3o-main)  
 * [ Rodando o Código](#rodando-o-c%C3%B3digo)  
 * [ Buscar informações reais](#buscar-informa%C3%A7%C3%B5es-reais)  
 * [ Conclusão](#conclus%C3%A3o) 

###### generated with [Summaryze Forem 🌱](https://summaryze-forem.vercel.app/)
## Primeiramente, o que é bitcoin? 
Bitcoin é uma forma de dinheiro, assim como o dólar, real, euro, a única diferença é que o bitcoin é uma moeda puramente digital, e não é emitido por nenhum governo. O seu valor, é definido individualmente pelos próprios indivíduos do mercado. 

## Como funciona as transações do bitcoin? 
Todas as transações ficam armazenadas em um "livro", que é o que chamamos de Ledger. Contudo, como existem milhares e milhares de transações, em vez de termos só um Ledger geral, nós temos milhares e milhares de ledgers também, sendo um conectado a seu antecessor. Desta forma fica muito mais fácil para pesquisarmos uma determinada transação. Está cadeia de ledgers são chamadas de blockchain (cadeia de blocos). 

## Criptografia/SHA-256
SHA-256, do inglês “Secure Hash Algorithm”, é uma função criptográfica utilizada como base do sistema de trabalho do Bitcoin. Essa função recebe uma entrada de tamanho aleatório e a converte em uma saída de tamanho fixo de 256 bits. As funções de hash são especiais por serem unidirecionais, ou seja, não podem produzir a entrada a partir da saída, mas sim uma saída quando recebem uma entrada. Além disso, o hash é calculado pelos mineradores para que uma transação possa ser adicionada à blockchain, funcionando como uma espécie de link entre os blocos, como já citado anteriormente. 
O SHA-256 recebe códigos de qualquer cumprimento e cria um algoritmo de comprimento fixado em 256 bits ou 64 caracteres. Ele recebe uma entrada particular, que podemos chamar de “mensagem”, e basicamente aplica um conjunto de transformações matemáticas nessa entrada para produzir uma única saída, a qual também não pode ser descriptografada, seguindo uma função unidirecional, como uma via de mão única.
## Qual a aplicação do SHA-256 no bitcoin? 
A função SHA-256 na mineração do Bitcoin se dá quando um indivíduo se torna elegível a fim de colocar novos blocos dentro da blockchain. Para concluir a tarefa, ele deve preencher o que seria um cabeçalho do bloco, que deve atender pelos 6 parâmetros impostos pelo protocolo, são eles:
1°- Versão: número da versão do software Bitcoin
2°- Hash do bloco anterior: referência ao hash do bloco anterior
3°- Raiz de Merkle: um hash representativo das transações incluídas no bloco
4°- Registro de data e hora: o horário em que o bloco foi criado
5°- Target: algoritimo de prova de trabalho para o bloco
6°- Nonce: a variável usada no processo de prova de trabalho
Para que um bloco seja adicionado ao cabeçalho ele deve ser colocado duas vezes no algoritmo SHA-256. 
Por exemplo:
Hash do bloco anterior = SHA-256(SHA-256(cabeçalho do bloco)). 
## Vamos para o código?
Primeiramente vamos importar 2 bibliotecas para que nosso código rode com sucesso! A primeira é a `hashlib`, e a segunda é a `time`. 
``` python 
from hashlib import sha256
import time
```
A `hashlib` utilizaremos para pegar a função sha256 tão importante nesta mineração, e a time será apenas para contabilizar o tempo em que nosso código ficará rodando. 
## Vamos testar como funciona essa função? 
``` python 
print(sha256('efk'.encode('ascii')))
```
Primeiramente, vou colocar tudo dentro de um print. Agora, chamei a função `sha256`, e passei os caracteres 'efk' para codificarmos. Contudo, esses caracteres estão no formato unicode, por isso, passamos o método encode, e passamos como parâmetro o 'ascii'. O resultado disso é: 
``` python 
<sha256 _hashlib.HASH object @ 0x0000025F1CFEA990>
```
Ele gerou um objeto no python. Para transformamos esse objeto em uma string python, vamos passar o método `hexdigest`. O código fica assim então: 
``` python 
print(sha256('efk'.encode('ascii')).hexdigest())
```
Gerando a saída: 
``` python 
7b450aa131c1b97d9573d30003b55290c1995d1258bb2596048c1c8cba3abd75
```
Ou seja, a string resultante, é o código criptografado para aqueles caracteres que passamos acima, 'efk'. 

## Funções do nosso script!
``` python 
def apply_sha256(texto):
    return sha256(texto.encode("ascii")).hexdigest()
```
``` python 
def mine(n_bloco, transacoes, hash_anterior, qtd_zeros):
    nonce = 0
    while True:
        text = str(n_bloco) + transacoes + hash_anterior + str(nonce)
        hash = apply_sha256(text)
        if hash.startswith("0"*qtd_zeros):
            return nonce,hash
        nonce+=1

```
Na função mine vamos precisar das informações que já foram mencionadas anteriormente, o número de blocos, as transações, o código do hash anterior, e a quantidade de zeros que é o que diz se aquele código é originado de um bitcoin. Saindo dos parâmetros, vamos definir nosso nonce como 0. Após isso, criamos um laço "infinito", e vamos definir a nossa variável de texto. Esta variável vai receber o número do bloco convertido para string, concatenado com as transações, concatenado com o hash anterior, e concatenado com o nonce convertido para string também. E agora vamos criar nossa variável hash, que vai receber nossa função apply_sha256(). Verificamos agora a quantidade de 0 que tem no nosso hash, para isso vamos utilizar o if, e vamos utilizar o método startswith, que é utilizado para identificar a quantidade de 0 iniciais na nossa string hash. Para que não passássemos inúmeros 0, passamos apenas um, e multiplicamos pela variável quantidade de zeros. Se este if for verdadeiro, entramos nele e retornamos o nonce e o hash, se ele não for, atribuímos +1 no valor do nonce, e o laço se repete até que a condição acima seja verdadeira.  

## Função main!
``` python 
if __name__ == "__main__":
    num_bloco = 15
    transacoes = """
    Eduardo->Tulio->2
    Adriano->Lucas->20
    Isabella->Joao->10"""
    qtde_zeros = 5
    hash_anterior = "abc"
    inicio = time.time()
    resultado = mine(num_bloco, transacoes, hash_anterior, qtde_zeros)
    print(resultado)
    print(time.time() - inicio)
```
Primeiro vamos declarar o número de blocos. Após isso, vamos declarar as transações, e logo em seguida vamos declarar a quantidade de zeros. Após isso vamos criar nosso hash anterior, e vou declarar uma variável que vai servir pra cronometrar o tempo que meu algoritmo dará o resultado. Vamos utilizar a função time() para isso. Por fim, criaremos uma variável resultado, e chamaremos a função mine(), passando todos os parâmetros necessários. Após isso, vamos printar o resultado, e o tempo que o algoritmo utilizou pra rodar. 
## Rodando o Código
``` python 
from hashlib import sha256
import time


def apply_sha256(texto):
    return sha256(texto.encode("ascii")).hexdigest()


def mine(n_bloco, transacoes, hash_anterior, qtde_zeros):
    nonce = 0
    while True:
        texto = str(n_bloco) + transacoes + hash_anterior + str(nonce)
        meu_hash = apply_sha256(texto)
        if meu_hash.startswith("0" * qtde_zeros):
            return nonce, meu_hash
        nonce += 1


if __name__ == "__main__":
    num_bloco = 15
    transacoes = """
    Eduardo->Tulio->2
    Adriano->Lucas->20
    Isabella->Joao->10"""
    qtde_zeros = 5
    hash_anterior = "abc"
    inicio = time.time()
    resultado = mine(num_bloco, transacoes, hash_anterior, qtde_zeros)
    print(resultado)
    print(time.time() - inicio)
```
E nossa saída é: 
``` python 
(1523970, '0000001be19bb67966b06b1261f729d0b00e3f557537184537378336f6989313')
3.2422425746917725
```
Primeiro temos o nonce, logo em seguida o hash, e por fim o tempo em segundos que ele demorou para executar este script. 

##Buscar informações reais
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bgy9wcqnxb7ks1r5fqh2.gif)

## Conclusão 
O script para minerar bitcoin é relativamente simples, contudo, é preciso uma máquina extremamente potente para que esta mineração seja eficiente. O número de 0 utilizados nestas minerações atualmente iniciam com 20, quanto mais 0, mais tempo de processamento. Para apenas exemplificar, utilizei números menores, mas podem tentar a vontade, só cuidado pra não explodir o computador kkkkkk.