Home » Programação » Criando o primeiro dApps na blockchain

Criando o primeiro dApps na blockchain

Compartilhe

What’s up guys!!

SPOILER: Se quiser ver a versão desse artigo em vídeo vá para o final da publicação.

Eu sou um grande entusiasta quando o assunto é blockchain, já tem algum tempo que venho estudando e investindo em criptomoedas (inclusive jogos NFT), e a cada dia que passa eu acredito mais que o caminho que iremos seguir é para uma rede descentralizada.

Nessa jornada pokémon crypto, estive envolvido em alguns projetos que envolveram e envolve o desenvolvimento na rede da blockchain, entre eles o projeto que estou trabalhando atualmente é o Sollar Ark, um jogo NFT que está tendo participação de um super time, no qual posso comentar com mais detalhes uma outra postagem no futuro, contando um pouco o processo de criação.

Sem mais delongas, o objetivo é que nesse primeiro artigo eu demonstre como que é “fácil” desenvolver um Smart Contract* na rede da blockchain.

O que é blockchain?

um sistema de base de dados que funciona de maneira distribuída, alimentado por diversos computadores. Na prática, acaba funcionando como um grande arquivo compartilhado de registros de transações. As informações inseridas no blockchain são imutáveis e verificadas por todos os computadores que fazem parte da mesma cadeia.

O que é web3?

web3 é a terceira geração da internet onde os dispositivos estão conectados em uma rede descentralizada ao invés de depender de servidores baseados em banco dados.

Desenvolvendo o primeiro dApp na blockchain

Primeiramente precisamos configurar o ambiente, para isso, você precisará de ter os seguintes itens:

  • Truffle
    Truffle é um framework de desenvolvimento para blockchain, com estrutura de testes e pipelines de ativos usando a Ethereum Virtual Machine (EVM), com o objetivo de facilitar a vida do desenvolvedor.
  • Ganache
    O Ganache CLI é a versão mais recente do TestRPC: um emulador de blockchain rápido e personalizável. Ele permite que você faça chamadas para o blockchain de forma rápida sem a sobrecarga de executar um nó Ethereum real (que tem alto tempo de espera por chamada)
  • Editor de código da sua preferência, exemplo, Visual Code ou Sublime Text.

Instalando truffle
Para instalar o truffle não tem segredo, primeiramente você precisará de ter o Node.js e em seguida abra o terminal do seu computador e digite o comando abaixo:

npm install -g truffle

Instalando Ganache
Ganache é mais simples, acessando o seguinte endereço https://trufflesuite.com/ganache/index.html clique para fazer o download no botão do seu sistema operacional, para instalar utilize apenas o avançar continuo até finalizar.

Configurando o Ganache
Após instalado o Ganache abra-o e iremos configurar, clique no botão new workspace.

Adicione um nome para identificar a sua rede da blockchain

Após adicionar o nome da sua area de trabalho, você pode configurar algumas informações sobre o servidor, por padrão e para fins de estudo você poderá manter a mesma configuração que eu fiz.

Pronto, ambiente configurado, bora trabalhar!

Crie um pasta para o seu projeto em algum diretório de sua preferência, após feito abra o terminal e navegue até a pasta criada, no meu caso eu fiz a pasta c:/Projetos/phpiando/hello-blockchain após acessar o diretório via terminal digite o comando abaixo para instalar os componentes principais do truffle.

$ truffle init

feito isso, você terá um resultado parecido com o meu print abaixo.
Obs: Ignore as pasta frontend falarei disso um pouco mais a frente.

Explicação da estrutura do projeto truffle:

  • Contracts
    Aqui fica todos os arquivos responsáveis aos contratos que serão implementando na blockchain.
  • Migrations
    Para que seus contratos sejam implementados na blockchain o mesmo precisará de ter as migrations, basicamente esse arquivo é responsável em pegar o seu contrato e implantar na rede da blockchain.
  • build
    Essa pasta é criada automaticamente quando você usa o comando “migrate” ou “compile” do truffle, aqui fica contratos no formato .JSON, esse arquivo você usará no frontend quando for acessar os métodos do seu contrato.
  • test
    Essa pasta fica responsável para armazenar os seus testes unitários de contratos, em outras palavras, é um local onde você consegue testar seu contrato antes mesmo de ir para o frontend, ganhando tempo em desenvolvimento.

Antes de iniciar, abra o arquivo truffle-config.js e retire os comentários e configure os dados igual ao exemplo abaixo.

Pronto, para já, iremos executar 3 comandos cada comando vai criar um arquivo na pasta de contracts, migrations e test, no seu terminal digite os seguintes comandos.

$ truffle create contract HelloWorld
$ truffle create migration HelloWorld
$ truffle create test HelloWorld

Acesse o arquivo dentro da pasta contracts e cole o conteúdo abaixo, deixei a explicação nas funções. No vídeo que encontra-se no final do post tem mais detalhes que eu explico o que significa alguns termos.

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract HelloWorld {
  string public greeting;

  constructor(){
    greeting = "Minha primeira mensagem na blockchain";
  }

  /**
  * Recupera o valor que a variável greeting tem
  * quando queremos recuperar valores de variáveis usaremos o termo "view"
  * ele deixa claro para blockchain que esse método apenas retornar valores e não alterará
  * métodos view não tem taxas de gas, ou seja, é gratuito.
  * @return string
   */
  function sayHello() public view returns(string memory){
    return greeting;
  }
  
  /**
  * Método para alterar o texto na variavel greeting
  * quando queremos recuperar valores de variavies usaremos o termo "view"
  * ele deixa claro para blockchain que esse método apenas retornar valores e nao alterará
  * métodos view não tem taxas de gas, ou seja, é gratuito.
  * @param greeting string
  * @return void
   */
  function updateGreeting(string memory _greeting) public{
    greeting = _greeting;
  }
}

Agora vamos editar o arquivo .js que foi criado na pasta migrations, para tal copie e cole o conteúdo que está abaixo.

const HelloWorld = artifacts.require("HelloWorld");

module.exports = async function(_deployer) {
  await _deployer.deploy(HelloWorld);
};

E por último na pasta test, abra o arquivo criado e cole o conteúdo abaixo:

const HelloWorld = artifacts.require("HelloWorld");

/*
 * uncomment accounts to access the test accounts made available by the
 * Ethereum client
 * See docs: https://www.trufflesuite.com/docs/truffle/testing/writing-tests-in-javascript
 */
contract("HelloWorld", ([alice, bob, cain]) => {
  const INITIAL_MESSAGE = "Meu primeira mensagem na blockchain";
  const UPDATE_MESSAGE = "Hello World - Blockchain";

  beforeEach(async function(){
    this.contract = await HelloWorld.deployed();
  });

  it("retrieving initial message from blockchain", async function () {    
    assert.equal(INITIAL_MESSAGE, (await this.contract.sayHello()));
  });

  it(`update message on blockchain ${UPDATE_MESSAGE}`, async function () {    
    await this.contract.updateGreeting(UPDATE_MESSAGE, {
      from: alice
    });
    assert.equal(UPDATE_MESSAGE, (await this.contract.sayHello()));
  });
});

Pronto, dessa maneira criamos o nosso primeiro dApp, vamos compilar e implantar na blockchain.

Primeiro comando que você poderá usar é o compile, esse comando vai identificar se tem algum erro no nosso contrato, para isso digite:

$ truffle compile

Em seguida, se não tiver erros no contrato vamos implantar na blockchain, para isso vamos usar o comando.

$ truffle migrate

Se tiver tudo ok no momento que implementou o seu contrato voce terá um resultado parecido com a mensagem abaixo:

1648481877_hello_world.js
=========================

   Deploying 'HelloWorld'
   ----------------------
   > transaction hash:    0x6ada8956ba82d82342d1ee5721b8303c7b31a18041dd7f4ce1579c027d5e4998
   > Blocks: 0            Seconds: 0
   > contract address:    0xB0A0479C9A27BdE176B9ddF327a51474f41774bd
   > block number:        5
   > block timestamp:     1648482648
   > account:             0xe94De5C95e2aF3792a7aC2E891Fd68F059752B63
   > balance:             99.98256992
   > gas used:            415758 (0x6580e)
   > gas price:           20 gwei
   > value sent:          0 ETH

Summary
=======
> Total deployments:   1
> Final cost:          0.00831516 ETH

Com isso, no nosso contrato já está na blockchain (no momento só no nosso computador).
Agora podemos usar o arquivo de teste e ver se nossas funções estão comportando da forma que deveria, para isso utilize o comando abaixo:

$ truffle test

Se todos os métodos estiverem certo, mostrará no console que passou, caso tenha algum erro ele indicará qual que está, porém até esse ponto acredito que você vai ter um retorno parecido o que está abaixo

Compiling your contracts...
===========================
> Compiling .\contracts\HelloWorld.sol
> Artifacts written to C:\Users\Roni\AppData\Local\Temp\test--5520-bYSyd4B4yqyr
> Compiled successfully using:
   - solc: 0.8.9+commit.e5eed63a.Emscripten.clang



  Contract: HelloWorld
    √ retrieving initial message from blockchain (164ms)
    √ update message on blockchain Hello World - Blockchain (574ms)


  2 passing (857ms)

Bom, até aqui nosso contrato já está funcionando, vamos usa-lo agora em um projeto “real” onde iremos utilizar um frontend para requisitar as funções no nosso contrato na blockchain, para essa parte eu já fiz um modelo de index.html e coloquei abaixo.
Coloquei comentário entretanto sobre o web3 e seus recursos deixo aqui o link da documentação oficial: https://web3js.readthedocs.io/en/v1.7.1/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Blockchain</title>
</head>
<body>
    <h1 id="message"></h1>
    <script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js@1.0.0-beta.34/dist/web3.min.js"></script>    
    <script>        
        var web3, contract;        

        /**
         * Esse método vai instanciar o web3, permitindo que acesse os recursos da blockchain.
         * */
        const getWeb3 = () => {
            return new Promise((resolve, reject) => {
                window.addEventListener("load", async () => {
                    web3 = new Web3("ws://localhost:7545");
                    resolve(web3);
                });
            });
        };

        /**
         * Método que vai retornar o nosso contrato.
         * Nesse caso utilizamos o recurso web3.eth.Contract, para isso passamos
         * 2 parametros, o ABI (que está no nosso arquivo) e o endereço, esse endereço
         * foi gerado na tela anterior quando utilizamos o "truffle migrate"
         * */
        const getContract = async () => {            
            /* 
            precisamos acessar nosso arquivo compilado que está na pasta 
            build/contracts (para esse teste utilize o arquivo index.html dentro de um
            ambiente como exemplo, xampp ou algo parecido.)
            */
            let data = await fetch('HelloWorld.json')
            .then(response => response.json());            
            
            contract = new web3.eth.Contract(
                data.abi,
                "0xB0A0479C9A27BdE176B9ddF327a51474f41774bd"
            );
            
            return contract;
        }

        /**
         * Esse método recupera o que temos na variavel greeting no contrato
         * quando queremos usar métodos que são do tipo "view" que retornará apenas
         * valores e nao mudará nada, usamos o método .call()
         * */
        const displayGreeting = async () => {
            const messageH1 = document.querySelector("#message");
            let message = await contract.methods.sayHello().call();
            messageH1.innerHTML = message;
        }

        /**
         * Esse método altera o que temos na variavel greeting no contrato
         * no caso quando usamos funções que altera o estado de variaveis e outros itens no contrato
         * utilizamos o recurso .send(), um outro detalhe, nessa transação precisamos pagar a taxa de 
         * gas, que é o custo de processar alguma coisa na blockchain
         * */
        const updateGreeting = async (newMessage) => {
            const accounts = await web3.eth.getAccounts();
            const owner = accounts[0];

            await contract.methods
                .updateGreeting(newMessage)
                .send({ from: owner, gas: 40000 });

            await displayGreeting();
        }

        async function greetingApp() {
            web3 = await getWeb3();            
            contract = await getContract();
            
            
            displayGreeting();            
        }

        greetingApp();
    </script>
</body>
</html>

Bom, esse é o primeiro modelo e exemplo de um código implementado na rede da blockchain.
Espero que ficou claro, entretanto, se tiver dúvidas estarei feliz em responder, deixe nos comentários.

*Smart contracts são sistemas de contratos utilizados para executar transações automaticamente sem a necessidade da uma empresa, governo ou entidade para intermediar.

Link Repositório GITHUB – https://github.com/over12/hello-worldblockchain