WEB3DEV

Cover image for Meu primeiro smart contract: Subindo meu primeiro smart contract para blockchain
ViniBlack
ViniBlack

Posted on • Atualizado em

Meu primeiro smart contract: Subindo meu primeiro smart contract para blockchain

Esse é o quinto post da série Meu primeiro smart contract, que tem a intenção de ensinar ao longo de sete semanas alguns conceitos do solidity até construirmos um token baseado no ERC-20 com alguns testes unitários.

Nesse post vamos entender o que é o hardhat e aprender a subir nosso contrato para uma rede de teste (testnet) utilizando o Alchemy para nos ajudar nessa parte.

Ferramentas

Nesse post vamos utilizar o VS Code para editar o código, o Node.js para instalar e executar o código, o Alchemy para nos ajudar a subir nosso contrato para uma rede de teste e a Metamask para administrarmos nossas carteiras.

Hardhat

Hardhat é um ambiente de desenvolvimento para software Ethereum. Ele consiste em diferentes componentes para editar, compilar, depurar e implantar seus contratos inteligentes e dApps, todos trabalhando juntos para criar um ambiente de desenvolvimento completo.

O Hardhat Runner é o principal componente com o qual você interage ao usar o Hardhat. É um executor de tarefas flexível e extensível que ajuda você a gerenciar e automatizar as tarefas recorrentes inerentes ao desenvolvimento de contratos inteligentes e dApps.

Caso queira saber mais sobre o Hardhat, clique aqui que é um tutorial de hardhat para iniciantes.

Instalação

No terminar do VS Code:
1 - Vamos criar o package.json com uma configuração base:

npm init -y
Enter fullscreen mode Exit fullscreen mode

2 - Vamos instalar o hardhat como dependência de desenvolvimento:

npm install --save-dev hardhat
Enter fullscreen mode Exit fullscreen mode

3 - Vamos criar um novo projeto:

npx hardhat
Enter fullscreen mode Exit fullscreen mode

3.1 - Esse comando irá te fazer algumas perguntas para saber que tipo de projeto você deseja criar, vamos criar um projeto JavaScript:

What do you want to do?
┗ Create a JavaScript project
Enter fullscreen mode Exit fullscreen mode

3.2 - Onde você deseja criar o projeto do hardhat:

Hardhat project root:
┗ Enter
Enter fullscreen mode Exit fullscreen mode

3.3 - Se deseja criar o arquivo .gitignore:

Do you want to add a .gitignore?
┗ Y
Enter fullscreen mode Exit fullscreen mode

3.4 - Se deseja compartilhar as informações do seu projeto com o Hardhat:

Help us improve Hardhat with anonymous crash reports & basic usage data?
┗ N
Enter fullscreen mode Exit fullscreen mode

3.5 - Se deseja já instalar as dependências do projeto:

Do you want to install this sample project's dependencies with npm (@nomicfoundation/hardhat-toolbox)?
┗ Y
Enter fullscreen mode Exit fullscreen mode

Após executar esses comandos o hardhat vai ter criado uma um projeto base para nós conseguirmos trabalhar.

Arquivos criado até agora

Vamos dar uma olhada nos arquivos que o hardhat criou e entender cada um deles.

Contracts

Dentro da pasta contracts é o lugar onde criamos nossos contratos inteligentes, vamos dar uma olhada no contrato Lock.

Lock

Esse contrato que o hardhat criou como exemplo, nos permite travar uma quantia de ether por um determinado tempo dentro do nosso contrato e depois que passar o tempo definido vamos conseguir retirar essa quantidade de ether.
Vamos mudar algumas coisas para seguir o mesmo padrão que utilizamos nos posts anteriores.
Dentro do arquivo Lock.sol vamos mudar a licença do contrato para GLP-3.0.

// SPDX-License-Identifier: GPL-3.0
Enter fullscreen mode Exit fullscreen mode

O contrato está importando o arquivo hardhat/console.sol que é o arquivo que contém algumas funções que nos permite utilizar o console para nos ajuda a debugar o nosso contrato, nativamente o solidity não tem suporte ao console, então importamos o arquivo hardhat/console.sol para que possamos usar o console.

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.9;

// Import this file to use console.log
import "hardhat/console.sol";
Enter fullscreen mode Exit fullscreen mode

Caso queira entender um pouco mais sobre importação de outros contratos, clique aqui

Variáveis

O nosso contrato tem duas variáveis: uma para salvar o dono do contrato owner e outra para salvar o tempo que será travado a quantidade de ether unlockTime.

uint public unlockTime;
address payable public owner;
Enter fullscreen mode Exit fullscreen mode

Evento

Temos um evento para enviar uma informação para o nosso front-end quando realizarmos a retirada de ether do contrato.

event Withdrawal(uint amount, uint when);
Enter fullscreen mode Exit fullscreen mode

Construtor

No constructor estamos fazendo uma verificação para ver se _unlockTime é maior que o block.timestamp, se for maior que o timestamp do bloco, então salvamos o tempo que o bloco será destravado e o dono do contrato.

constructor(uint _unlockTime) payable {
  require(
    block.timestamp < _unlockTime,
    "Unlock time should be in the future"
  );

  unlockTime = _unlockTime;
  owner = payable(msg.sender);
}
Enter fullscreen mode Exit fullscreen mode

Saldo do contrato

Para facilitar o nosso entendimento mais para frente vamos criar uma função chamada balanceOf que retorna o saldo do contrato.

function balanceOf() public view returns(uint){
  return address(this).balance;
}
Enter fullscreen mode Exit fullscreen mode

Retirar Ethers

Antes de retirar os ethers do contrato, é feita uma verificação se o contrato está destravado e se quem chamou a função é o dono do contrato.
Se passar pelas verificações, então é feita a retirada dos Ethers do contrato.

function withdraw() public {
  // Uncomment this line to print a log in your terminal
  console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp); // {1}

  require(block.timestamp >= unlockTime, "You can't withdraw yet");
  require(msg.sender == owner, "You aren't the owner");

  emit Withdrawal(address(this).balance, block.timestamp);

  owner.transfer(address(this).balance);
}
Enter fullscreen mode Exit fullscreen mode

Na linha {1} podemos descomentar essa linha para verificar o timestamp que o contrato será destravado e o timestamp atual.

Scripts

Dentro da pasta scripts é o lugar onde podemos escrever scripts para compilar nossos contratos e implementá-los em uma rede ativa ou em uma rede de teste.

Deploy

Deploy significa implantar, isso quer dizer que quando fazemos um deploy estamos subindo nosso contrato para blockchain para que outras pessoas possam ver nosso contrato e interagir com ele.
Vamos dar uma olhada no arquivo deploy.js que é o arquivo que contém todas as informações para subir nosso contrato para a blockchain.

Na variável hre estamos realizando uma importação das funções do hardhat com o require que é uma instrução node.js embutida e é mais comumente usada para incluir módulos de outros arquivos separados, resumidamente é mais ou menos igual o import que vimos mais cedo.

const hre = require("hardhat");
Enter fullscreen mode Exit fullscreen mode

O hardhat criou uma função assíncrona chamada main, quando chamamos uma função assíncrona, ela retorna uma promessa que quando resolvida, retorna o valor que queremos ou um erro caso ocorra algum.

Dentro da função main estamos usando a função round da biblioteca Math do JavaScript, ela pega um número decimal e arredonda para baixo e dentro dele estamos pegando o nosso tempo atual dividindo por 1000 para conseguirmos pegar o tempo em milisegundos e salvando tudo isso dentro da variavel currentTimestampInSeconds.

const currentTimestampInSeconds = Math.round(Date.now() / 1000);
Enter fullscreen mode Exit fullscreen mode

Após isso existe uma variável chamada ONE_YEAR_IN_SECS que é o tempo que o contrato será destravado em segundos. Vamos mudar essa variável para que o contrato seja destravado em um tempo menor.

const ONE_YEAR_IN_SECS = 5 * 60;
Enter fullscreen mode Exit fullscreen mode

Caso queira deixar mudar o nome da variável para ficar igual a operação que está sendo atribuída a ela você pode mudar o nome dela para FIVE_MINUTES_IN_SECS.

E no final de tudo vamos somar o valor de currentTimestampInSeconds + FIVE_MINUTES_IN_SECS e atribuir esse resultado para variável unlockTime.

const currentTimestampInSeconds = Math.round(Date.now() / 1000);
const FIVE_MINUTES_IN_SECS = 5 * 60;
const unlockTime = currentTimestampInSeconds + FIVE_MINUTES_IN_SECS;
Enter fullscreen mode Exit fullscreen mode

Agora vamos mudar a variável lockedAmount que agora irá passar 0.01 Ether para o contrato, precisamos mudar a quantidade de ethers que será enviada para o contrato para conseguirmos subir o contrato para blockchain.

const lockedAmount = hre.ethers.utils.parseEther("0.01");
Enter fullscreen mode Exit fullscreen mode

Na variável Lock estamos se conectando ao nosso contrato e na variável lock estamos fazendo o deploy do contrato passando o tempo que o contrato ficará travado e a quantidade de Ethers que ficarão travadas.

const Lock = await hre.ethers.getContractFactory("Lock");
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
Enter fullscreen mode Exit fullscreen mode

Vamos esperar o deploy do contrato e após isso vamos escrever no console o endereço do contrato que subiu para a blockchain.

await lock.deployed();

console.log("Lock with 1 ETH deployed to:", lock.address);
Enter fullscreen mode Exit fullscreen mode

O hardhat criou essa função para conseguirmos usar async/await em todos os lugares do arquivo e mostrar o erro no console caso aconteça algum.

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
Enter fullscreen mode Exit fullscreen mode

Test

Dentro da pasta test é o lugar onde podemos escrever os testes para nossos contratos.
Nos próximos posts vamos entrar em mais detalhes sobre testes.

Artifacts

Quando um contrato inteligente é compilado com sucesso é criado um arquivo JSON para esse contrato, esse arquivo fica salvo na pasta artifacts, esse JSON tem informações importantes sobre o contrato de maneira organizada, tais como bytecode, ABI, detalhes do deploy, versão, entre outras coisas.
Conseguimos utilizar os JSONs para interagir com algumas bibliotecas e fazer a conexão entre frontend e o contrato, por exemplo.

Cache

O diretório usado pelo Hardhat para armazenar em cache seus itens internos.

Node_modules

Dentro da pasta node_modules é um diretório criado pelo npm ela serve para guardar todos os arquivos das dependências que instalamos no nosso projeto.

Arquivos

  • .gitignore: Arquivo que é usado para ignorar arquivos/pastas que não queremos que o git acompanhe.
  • hardhat.config.js: Arquivo que é usado para configurar o hardhat.
  • package-lock.json: Arquivo que descreve a árvore exata das dependências que foram geradas para permitir que as instalações subsequentes tenham a árvore idêntica.
  • package.json: Nesse arquivo armazena as informações básicas sobre as dependências do projeto.
  • README.md: Arquivo que é usado para documentar o projeto.

Subindo o contrato para a blockchain

Para conseguirmos subir o contrato para blockchain precisamos fazer algumas coisas antes.

Dotenv

Abra seu terminal na pasta do nosso projeto, e execute o seguinte comando.

npm install --save-dev dotenv
Enter fullscreen mode Exit fullscreen mode

Com o dotenv conseguimos criar variáveis ​​de ambiente para cada ambiente da nossa aplicação.

Crie um um arquivo chamado .env, dentro dele vamos criar algumas variáveis de ambiente, fazermos isso porque vamos ter que utilizar algumas chaves de aplicação que não pode subir para internet.
Criando o arquivo .env

Alchemy

No site do Alchemy, após você ter criado uma conta e se logado, dentro do dashboard clique no botão "Create app"
Criando um novo projeto no alchemy

Escreva o nome da sua aplicação, escreva uma descrição, selecione a chain "Ethereum", a network "Goerli" e clique em "Create App"
Criando um novo app no alchemy

Clicando no nome do projeto vamos ser direcionado para tela da aplicação, onde podemos ter mais informações sobre o uso da aplicação
Entrando na aplicação

Clique em "View key" e copie a chave "HTTPS".
TOME CUIDADO PARA NÃO COMPARTILHAR ESSAS INFORMAÇÕES COM OUTRAS PESSOAS.
Copiando chave https

Dentro do arquivo .env vamos informar nossa chave "HTTPS"

STAGING_ALCHEMY_KEY="COLE AQUI SUA CHAVE HTTPS"
Enter fullscreen mode Exit fullscreen mode

Metamask

Caso você não tenha instalado o Metamask, de uma olhada nesse video que ensina como instalar e configurar a MetaMask.
Com a Metamask configurada, clique na sua "foto" e entre em "settings".
Entrando nas configurações da metamask

Clique em "Advanced".
Entrando nas configurações avançadas

Desça a página até encontrar a opção "Show test networks" e ative essa opção
Ativando a visualização de redes de testes

Após ativarmos isso vamos conseguir não só ver as redes Mainnet mas também as redes Testnet.
Agora clique em "Ethereum Mainnet" e mude para "Goerli Test Network"
Mudando a rede na metamask

Para conseguirmos subir nossos contratos para blockchain vamos precisar de dinheiro para pagar o GAS da transação, mas não precisa se preocupar, como estamos usando uma rede de teste tudo lá é de mentira até o dinheiro, para isso existe as torneiras de moeda entre nesse site Goerli faucet, copie o endereço da sua carteira.
Copiando o endereço da carteira
E informe o seu endereço e clique em "Send Me ETH".
Pedindo alguns ETH na rede goerli

Agora precisamos pegar uma informação da nossa carteira, vamos clicar nos três pontos e clicar em "Account details".
Visualizando mais detalhes do nosso endereço

Clique em "Export Private Key".
Exportando a chave privada do nosso endereço
Informe a senha da sua carteira.
Informando nossa senha
Após isso, irá carregar a chave da nossa carteira.
TOME CUIDADO COM ESSA CHAVE, NUNCA ENVIE OU COLOQUE ELA EM NENHUM LUGAR DA INTERNET, COM ESSA CHAVE QUALQUER PESSOA CONSEGUE FAZER TRANSFERÊNCIA DA SUA CARTEIRA SEM PRECISAR DA SUA SENHA.
Cópiando a nossa chave privada

Dentro do arquivo .env vamos informar nossa "PRIVATE_KEY"

STAGING_ALCHEMY_KEY="COLE AQUI SUA CHAVE HTTPS"
PRIVATE_KEY="COLE AQUI SUA PRIVATE KEY"
Enter fullscreen mode Exit fullscreen mode

Dentro do arquivo hardhat.config.js vamos adicionar algumas informações da nossa networks utilizando as variáveis de ambiente que criamos mais cedo e importar os arquivos do dotenv.

require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.9",
  networks: {
    goerli: {
      url: process.env.STAGING_ALCHEMY_KEY,
      accounts: [process.env.PRIVATE_KEY],
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

No seu terminal na pasta do nosso projeto, vamos executar o seguinte comando:

npx hardhat run scripts/deploy.js --network goerli
Enter fullscreen mode Exit fullscreen mode

Se tudo estiver certo esse comando irá realizar o deploy do nosso contrato para blockchain, e ira retornar o endereço do nosso contrato.
Endereço do nosso contrato

Copiando esse endereço e entrando no Goerli Etherscan conseguimos ver o nosso contrato na blockchain.
Nosso contrato na blockchain

Clique aqui para ver o contrato que subimos para blockchain nesse post.

Conclusão

Esse foi o quinto post da série de posts "Meu primeiro smart contract".
Se tudo deu certo, agora você tem o hardhat configurado na sua máquina para fazer deploy de smart contracts para blockchain e tem o seu primeiro smart contract rodando na testnet Goerli sendo gerenciado pelo Alchemy.

Se você gostou do conteúdo e te ajudou de alguma forma, deixe um like para ajudar o conteúdo a chegar para mais pessoas.

deixa um like


Link do repositório

https://github.com/viniblack/meu-primeiro-smart-contract

Vamos trocar uma ideia ?

Fique a vontade para me chamar para trocarmos uma ideia, aqui embaixo está meu contato.

https://www.linkedin.com/in/viniblack/

Latest comments (1)

Collapse
 
alexcustodio profile image
Alex Custódio

ótimo trabalho como sempre!