Protegendo Blockchain com Prova de Trabalho

Packt_Pub Blocked Unblock Seguir Seguindo 10 de janeiro

Saiba como a Prova de Trabalho é essencial para garantir blockchain neste artigo por Eric Traub, engenheiro de software em Nova York, com uma vasta experiência trabalhando como professor e instruindo pessoas em uma variedade de assuntos diferentes.

O que é uma prova de trabalho?

O método proofOfWork é muito importante e essencial para a tecnologia blockchain porque torna o Bitcoin e muitos outros blockchains seguros.

Agora, você deve estar curioso sobre o que é realmente uma Prova de Trabalho ( PoW ). Dê uma olhada em qualquer blockchain – cada blockchain é basicamente uma lista de blocos. Cada bloco único deve ser criado e adicionado à cadeia. No entanto, não queremos apenas que qualquer bloco seja criado e adicionado à cadeia. Queremos ter certeza de que cada bloco adicionado à cadeia seja legítimo, tenha as transações corretas e tenha os dados corretos dentro dele. Isso porque, se ele não tiver as transações corretas ou os dados corretos, as pessoas podem fingir o quanto eles têm de Bitcoin e, essencialmente, causar fraude e roubar dinheiro de outras pessoas. Toda vez que um novo bloco é criado, primeiro temos que ter certeza de que é um bloco legítimo, minerando-o através do PoW.

Um método proofOfWork currentBlockData o currentBlockData e o previousBlockHash . A partir desses dados, o método proofOfWork tentará gerar um hash específico. Este hash específico em nosso exemplo será um hash que começa com quatro zeros. Assim, com o dado currentBlockData e o previousBlockHash , o método irá de alguma forma gerar um hash resultante que começa com quatro zeros.

Agora vamos tentar entender como podemos fazer isso. Suponha que o hash seja aleatório. Então, se o hash resultante é efetivamente aleatório, como podemos gerar um hash do nosso bloco atual que começa com quatro zeros? A única maneira que isso pode ser feito é por tentativa e erro, ou por adivinhação e verificação. Então, o que teremos que fazer é executar nosso método hashBlock muitas vezes até que tenhamos sorte gerando um hash que tenha quatro zeros no começo.

Você pode estar se perguntando qual é a entrada do nosso método hashBlock – eles são previousBlockHash parâmetros previousBlockHash , currentBlockData e nonce . Como esses três parâmetros que foram passados uma vez e possivelmente gerar vários hashes diferentes quando estamos sempre passando exatamente os mesmos dados?

Como podemos alterar esses dados de uma maneira que não altere nossos currentBlockData ou o previousBlockHash , mas ainda obtemos um hash resultante com quatro zeros no início dele? A resposta a essa pergunta é que vamos mudar constantemente o valor do nonce . Isso tudo pode parecer um pouco confuso agora, então vamos tentar esclarecê-lo sabendo o que realmente acontece em um proofOfWork , dividindo-o um pouco.

O que acontece em nosso proofOfWork é que vamos repetidamente alterar nosso bloco até encontrarmos o hash correto, que será qualquer hash que comece com quatro zeros. Nós estaremos mudando a entrada para o nosso método hashBlock incrementando constantemente o valor nonce . A primeira vez que executamos nosso método hashBlock ; vamos começar com um valor de zero de zero.

Então, se o hash resultante não tiver quatro zeros no começo dele, vamos executar nosso método hashBlock novamente, exceto que desta vez vamos incrementar nosso valor nonce em 1. Se não obtivermos o valor hash correto Novamente, vamos incrementar o valor nonce e tentar novamente. Se isso não funcionar, novamente incrementaremos o valor de nonce e tentaremos novamente. Então nós continuamente hashBlock este método hashBlock até encontrarmos um hash que comece com quatro zeros. É assim que nosso método proofOfWork funcionará.

Você pode estar se perguntando como esse método proofOfWork realmente protege o blockchain. A razão para isso é que, para gerar o hash correto, teremos que executar nosso método hashBlock muitas vezes, e isso consumirá muita energia e poder de computação.

Então, se alguém quisesse voltar ao blockchain e tentar mudar um bloco ou os dados naquele bloco – talvez para se dar mais Bitcoin – eles teriam que fazer numerosos cálculos e gastar uma grande quantidade de energia para criar o hash correto. . Na maioria dos casos, voltar atrás e tentar recriar um bloco já existente ou tentar remendar um bloco já existente com seus próprios dados falsos não é viável. hashBlock método hashBlock não apenas hashBlock os currentBlockData , mas também recebe o BlockHash anterior. Isso significa que todos os blocos no blockchain estão vinculados por seus dados.

Se alguém tentar voltar e re-minerar ou recriar um bloco que já existe, eles também teriam que recriar e recriar todos os blocos que vierem depois do primeiro que eles recriaram. Isso levaria uma quantidade incrível de cálculo e energia e não é viável para um blockchain bem desenvolvido. Uma pessoa teria que entrar, recriar um bloco usando uma prova de trabalho e depois recriar cada bloco depois disso, fazendo uma nova prova de trabalho para cada bloco. Isso não é viável para qualquer blockchain bem produzido, e essa é a razão pela qual a tecnologia blockchain é tão segura.

Isso tudo pode parecer um pouco confuso e um pouco confuso agora, mas não se preocupe – vamos construir o método proofOfWork na seção a seguir e, em seguida, vamos testá-lo com muitos tipos diferentes de dados.

Criando o método proofOfWork

Vamos construir o método proofOfWork :

  1. Após o método hashBlock , defina o método proofOfWork seguinte maneira:

2. Este método aceita dois parâmetros: previousBlockHash e currentBlockData :

3. A primeira coisa que queremos fazer dentro do nosso método é definir um nonce:

4. Em seguida, queremos fazer o hash de todos os nossos dados pela primeira vez, então digite a seguinte linha de código destacada:

No código anterior, você pode perceber que usamos o termo let porque tanto nosso nonce quanto o hash estarão mudando conforme nos movemos através do método.

5. O próximo passo que queremos fazer é executar constantemente o método hashBlock várias vezes até obtermos um hash que comece com quatro zeros. Nós vamos fazer esta operação repetida com a ajuda de um loop while:

6. Se o hash que criamos não começar com quatro zeros, vamos querer executar o hash novamente, exceto desta vez com o valor diferente de nonce. Conseqüentemente, dentro do loop while, adicione as seguintes linhas destacadas de código:

Dentro do loop while, estamos executando nosso método hashBlock novamente com todos os mesmos dados, exceto que desta vez nosso nonce é incrementado e igual a 1 ao invés de 0. Esta será a primeira iteração de nosso loop while.

Agora, após a primeira iteração, o novo hash gerado não possui os primeiros quatro caracteres iguais a 0000. Nesse caso, queremos gerar um novo hash. Então, nosso loop while será executado novamente, o valor nonce será incrementado para 2 e um novo hash será criado. Se esse hash também não iniciar com quatro zeros, o loop while será executado novamente, o valor de nonce será incrementado novamente e o hash será gerado novamente.

Nosso loop continuará fazendo isso até acabar com um hash que começa com quatro zeros. Isso pode levar muitas iterações. Isso pode acontecer 10 vezes, 10.000 vezes ou 100.000 vezes.

Este loop é onde todos os cálculos serão realizados, e esta é a razão pela qual o método proofOfWork usa tanta energia – há muitos cálculos sendo feitos.

Continuaremos percorrendo o loop while até gerarmos um hash adequado que comece com quatro zeros. Quando finalmente tivermos o hash correto, nosso loop while irá parar de funcionar e, ao final de nosso proofOfWork , ele simplesmente retornará o valor nonce que nos forneceu o hash válido:

Então, é assim que nosso método proofOfWork funcionará e validará o hash. Na seção a seguir, testaremos nosso método proofOfWork para garantir que ele funcione corretamente. Também estudaremos porque retornamos um valor nonce vez de retornar o hash.

Testando o método proofOfWork

Vamos testar nosso método proofOfWork para garantir que ele funcione corretamente. Nós estaremos testando o método em nosso arquivo test.js Você pode encontrar os arquivos de código para este artigo em https://github.com/PacktPublishing/Learn-Blockchain-Programming-with-JavaScript/tree/master/dev . Então vamos começar:

  1. Abra o arquivo test.js.

2. Se você não tiver dados no arquivo test.js, inclua isso no arquivo test.js, conforme mostrado na captura de tela anterior, e você poderá começar a testar os dados.

3. Para testar nosso método proofOfWork , precisamos do previousBlockHash e currentBlockData . Então, em nosso caso de teste, livre-se do valor nonce e inclua as seguintes linhas de código em nosso arquivo:

Agora, o que devemos obter como resultado deste método proofOfWork é um valor nonce . O que nosso método proofOfWork faz é testar para ver se o valor correto de nonce é para hash com nossos dados de bloco e nosso previousBlockHash para gerar um hash de bloco resultante que começa com quatro zeros. Aqui, o proofOfWork encontra o nonce correto para nós.

4. Salve este arquivo e execute nosso teste digitando o comando node dev/test.js em nossa janela de terminal. Após o teste ser executado, você observará que um número aparece como uma saída na tela:

O que este número significa é que foram necessárias 27.470 iterações para o nosso método proofOfWork para encontrar um hash que começa com quatro zeros.

5. Para entender todo esse processo em profundidade, o que podemos fazer é, dentro de nosso loop while, sair de cada hash que tentamos. Teremos que fazer pequenas modificações no nosso loop while:

Quando executamos nosso arquivo de teste agora, o que vai acontecer é que deveríamos ver 27.000 hashes diferentes logados dentro do nosso terminal. Nenhum desses hashes começará com quatro zeros, exceto o último. Somente o ultimo hash que é desconectado deve começar com quatro zeros, porque depois do nosso método, isso terminará e retornará o valor nonce para o qual o hash válido foi obtido.

Salve nosso arquivo test.js novamente. Agora você pode observar em sua tela que temos vários hashes diferentes sendo desconectados do terminal:

Observe que, para cada hash que foi registrado, o começo nunca é quatro zeros seguidos até obtermos nosso valor final.

O que está acontecendo aqui é que estamos gerando o hash de nossos currentBlockData , previousBlockHash e nonce do valor 0. Então, para o próximo hash, estamos incrementando o nonce por 1. Então, são todos os mesmos dados de entrada, mas o nonce valor é incrementado até que o hash válido seja obtido. Finalmente, em 27.470, com o valor de um nonce, o hash válido é obtido.

Agora vamos tentar usar nosso método hashBlock . Em nosso dev/test.js file , exclua o método proofOfWork e inclua a seguinte linha de código:

No código anterior, para o nonce, vamos introduzir o valor 27,470. Este valor que obtivemos do nosso método proofOfWork .

O que podemos observar como saída é executar o único hash com o valor de nonce correto que obtivemos executando o método proofOfWork . Ao fazer isso, devemos gerar um hash que comece com quatro zeros na primeira tentativa. Vamos salvá-lo e executá-lo. Depois que o teste for executado, você poderá observar o único hash que começa com quatro zeros, conforme mostrado na captura de tela a seguir:

O proofOfWork é uma parte muito importante da tecnologia blockchain. É muito difícil calcular, como você pode observar nos resultados dos testes – foram necessárias mais de 27.000 iterações para gerar o hash correto. Consequentemente, um proofOfWork absorve muita energia e muitos cálculos e é muito difícil de produzir.

Uma vez que tenhamos a prova correta ou o valor nonce no qual o hash desejado é gerado, deve ser muito fácil para nós verificar se temos o valor correto de nonce. Podemos verificar isso simplesmente passando-o para o nosso método hashBlockhashBlock o hash que começa com quatro zeros.

É preciso muito trabalho para gerar uma prova de trabalho, mas é muito fácil verificar se está correto. Então, se alguma vez quisermos voltar ao nosso blockchain e verificar se um bloco é válido, tudo o que você precisa fazer é manipular os dados desse bloco com o hash do bloco anterior e o nonce que foi gerado a partir do proofOfWork quando esse bloco foi extraído. Se isso retorna um hash válido para nós que começam com quatro zeros, então já sabemos que o bloco é válido.

Assim, a partir do nosso teste, podemos concluir que o método proofOfWork funciona como esperado.

Se você achou este artigo interessante, você pode ver Aprender Blockchain Programming com JavaScript para explorar os fundamentos da tecnologia blockchain com JavaScript para desenvolver aplicações altamente seguras semelhantes a bitcoins. Aprender Blockchain Programação com JavaScript pode ajudar você a entender como funções de rede blockchain descentralizadas e porque descentralização é um recurso tão importante para proteger um blockchain.