DEV Community

loading...
Cover image for Minerador de bitcoin com PYTHON?!

Minerador de bitcoin com PYTHON?!

DevShy
Data Engineer | pythonist | love chess | challenge me
・6 min read
generated with Summaryze Forem 🌱

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.

from hashlib import sha256
import time
Enter fullscreen mode Exit fullscreen mode

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?

print(sha256('efk'.encode('ascii')))
Enter fullscreen mode Exit fullscreen mode

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 é:

<sha256 _hashlib.HASH object @ 0x0000025F1CFEA990>
Enter fullscreen mode Exit fullscreen mode

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:

print(sha256('efk'.encode('ascii')).hexdigest())
Enter fullscreen mode Exit fullscreen mode

Gerando a saída:

7b450aa131c1b97d9573d30003b55290c1995d1258bb2596048c1c8cba3abd75
Enter fullscreen mode Exit fullscreen mode

Ou seja, a string resultante, é o código criptografado para aqueles caracteres que passamos acima, 'efk'.

Funções do nosso script!

def apply_sha256(texto):
    return sha256(texto.encode("ascii")).hexdigest()
Enter fullscreen mode Exit fullscreen mode
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

Enter fullscreen mode Exit fullscreen mode

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!

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)
Enter fullscreen mode Exit fullscreen mode

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

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)
Enter fullscreen mode Exit fullscreen mode

E nossa saída é:

(1523970, '0000001be19bb67966b06b1261f729d0b00e3f557537184537378336f6989313')
3.2422425746917725
Enter fullscreen mode Exit fullscreen mode

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

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.

Discussion (0)