Como implementar o Blockchain em JavaScript

Ouvimos falar sobre Bitcoin, Ethereum além de outras moedas praticamente todos os dias. 2017 afinal, foi o ano das cryptocurrencies. Nesse post porém, não vou focar em nenhuma dessas moedas digitais. Mas sim na tecnologia por trás delas, que muitas pessoas dizem ser tão revolucionárias quanto a própria internet, o Blockchain. A ideia é implementar
Como implementar o Blockchain em JavaScript

Ouvimos falar sobre Bitcoin, Ethereum além de outras moedas praticamente todos
os dias. 2017 afinal, foi o ano das
cryptocurrencies.

Nesse post porém, não vou focar em nenhuma dessas moedas digitais. Mas sim na
tecnologia por trás delas, que muitas pessoas dizem ser tão revolucionárias
quanto a própria
internet
,
o Blockchain.

A ideia é implementar passo-a-passo uma versão simplificada do Blockchain em
JavaScript e ir explicando como essa tecnologia disruptiva funciona por baixo
dos panos.

Então, continue lendo esse post para aprender:

  • O que é e como funciona o Blockchain
  • Proof of Work?
  • Pra que servem os Blocos
  • O que é Mineração

Introdução

O Blockchain parece uma tecnologia de outro mundo e gera muitas dúvidas. Apesar
disso, é algo extremamente fácil de definir:

O Blockchain nada mais é do que um banco de dados aberto e distribuído.

Esse banco de dados é composto de Blocos. E todos esses Blocos são ligados entre
si em uma sequência. Daí o nome, Blockchain (cadeia de blocos).

Além disso, esse banco de dados é imutável. E faz sentido que seja.

Imagina se fosse possível que alguém intencionalmente modificasse sua conta.
Agora os 10 Bitcoins que você possui viraram 1.

Blocos

Vamos começar a implementação pela parte mais fácil: os Blocos. A estrutura de
um Bloco deve possuir os seguintes campos:

  • index
  • timestamp
  • hash
  • previousHash
  • data


Crédito:
https://medium.com/@lhartikk/a-blockchain-in-200-lines-of-code-963cc1cc0e54

O index e o timestamp são campos comuns em praticamente todos bancos de
dados. O campo data serve principalmente pra guardar transações mas podemos
também colocar outras informações. O hash é calculado internamente e serve pra
manter a integridade de cada Bloco e a segurança de todo o sistema (como vamos
ver no final do post). E por final, o previousHash é o elo de ligação que
liga cada Bloco ao seu Bloco anterior.

Com isso, temos a primeira implementação de um Bloco:

A função generateHash usa a biblioteca externa
crypto-js pra gerar o hash seguindo o
padrão sha256.

Parece complicado, mas tudo o que você precisa saber é que essa função vai
receber uma string como por exemplo:

foo

E vai retornar uma string encriptada:

2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae

Agora que já temos uma versão mínima de um Bloco, já podemos começar a construir
o Blockchain, que como falei anteriormente é uma sequência de Blocos ligados
entre si.

Com isso, essa é a primeira versão do Blockchain:

No construtor da classe, temos o array de Blocos inicializado já com o
Genesis Block (o primeiro bloco
criado no registro do Bitcoin). Adicionei também o index para poder
incrementar toda vez que um novo Bloco for adicionado no Blockchain.

Além disso duas funções foram criadas:

  • getLastBlock
  • addBlock

A primeira é extremamente simples, ela serve pra pegar o último Bloco que foi
criado.

A segunda é uma pouco mais complicada, mas também não é nada de outro mundo. Ela
serve pra adicionar novos Blocos ao Blockchain.

Integridade

Apesar de a versão anterior já funcionar razoavelmente bem, precisamos adicionar
alguma garantia de que o Blockchain não tenha sido alterado por algum ataque
malicioso.

Precisamos adicionar uma nova função para checar a integridade do Blockchain:

Lembrando que para verificarmos a integridade do Blockchain precisamos garantir
três características:

  • O hash de cada Bloco foi gerado corretamente
  • O index dos Blocos está em sequência
  • Os Blocos estão ligados entre si através dos hashes

Com essa simples função podemos testar se modificações maliciosas foram feitas e
se o Blockchain deve ser invalidado:

E finalmente com isso já temos uma primeira versão básica e funcional do
Blockchain em JavaScript:


Problemas

Apesar de já termos uma versão inicial funcionando, ainda podemos melhorar
bastante a nossa implementação.

Um dos problemas com essa versão atual é que usuários podem criar novos Blocos
de forma muito rápida, podendo invalidar o Blockchain, ou coisas ainda piores.
Não vou entrar em muitos detalhes dessa particularidade da tecnologia, mas o
post abaixo faz um excelente trabalho nesse sentido:

Explaining blockchain — how proof of work enables trustless consensus

Em resumo, precisamos de alguma ferramenta que não permita que usuários possam
criar Blocos desenfreadamente.

Proof of Work

O conceito de Proof of Work, como o próprio nome já sugere, é um mecanismo que
faz com que um usuário tenha um trabalho computacional significativo ao realizar
determinada tarefa.

Essa ferramenta já era utilizada antes do Bitcoin ser inventado para evitar por
exemplo spams e ataques
DoS
.

No Bitcoin, o Proof of Work funciona da seguinte forma: o hash que é gerado
automaticamente em cada Bloco deve começar com uma quantidade X de zeros,
dependendo da dificuldade geral do sistema.

Por exemplo, se a dificuldade geral do sistema for 1, esse hash é inválido
porque não começa com um zero:

a5036427617139d3ad9bf650d74ae43710e36d4f63829b92b807da37c5d38e8d

Porém, esse outro hash é válido porque começa com um zero:

07da8bff6cfea68a3f0a5bafc9b24d07f503e2282db36ffb58d43f9f4857c54b

Sempre que um usuário for criar um novo Bloco, ele vai precisar criar diversos
hashes até que um deles tenha a quantidade de zeros no começo fazendo com que
a regra geral do sistema seja atendida.

Ah, o nome disso é Mineração.

Lembrando que quanto maior o número de zeros que devem estar no começo do
hash, maior o poder computacional necessário para a tarefa.

Dito isso, vamos agora implementar a versão final do Blockchain com a mineração.

Primeiramente vamos alterar os Blocos.

No construtor, adicionamos os campos difficulty (dificuldade geral do sistema)
e nonce (quantidade de tentativas até que o hash correto seja criado). Além
disso, temos também um chamada para a função mine.

A função mine vai criar hashes até que a quantidade de zeros à esquerda do
hash seja atentida.

Lembrando que para que os hashes criados sejam diferentes, devemos adicionar o
campo nonce na função generateHash:

Com isso temos a versão final do Blocos com a mineração:

Agora basta alterarmos o Blockchain para que o campo difficulty seja passado
para os Blocos:

E é só isso :)

Lembrando que o código está todo no GitHub.

Ah, se você quiser saber mais sobre o Blockchain:

Outras implementações:

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *