WEB3DEV

Cover image for Meu primeiro smart contract: Aprendendo um pouco mais sobre smart contract
ViniBlack
ViniBlack

Posted on • Atualizado em • Originalmente publicado em dev.to

Meu primeiro smart contract: Aprendendo um pouco mais sobre smart contract

Esse é o segundo 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 criar um contrato básico de um banco, onde você vai conseguir depositar uma quantidade de "dinheiro" e mudar o dono do contrato.

Ferramentas

Vamos continuar usando Remix IDE para criação dos nossos contratos.

Criando um novo arquivo

Vamos criar um novo arquivo dentro da pasta contracts chamado 01-bank.sol

Criando o novo contrato 01-bank.sol

Dentro do arquivo 01-bank.sol, vamos declarar as licenças do nosso contrato, a versão do solidity e dar um nome para o contrato.

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Bank {

}
Enter fullscreen mode Exit fullscreen mode

Organização do código

Não existe uma forma certa de estruturar o código dos nossos contratos, mas para facilitar o entendimento vamos utilizar o seguinte padrão:

Estrutura do código

  1. Properties: Onde definimos nossas variáveis;
  2. Modifiers: Onde definimos nossos modificadores, (nesse post vamos entender para que serve);
  3. Events: Onde definimos nossos eventos, (nesse post vamos entender como funciona);
  4. Constructor: Onde definimos nosso construtor;
  5. Public Functions: Onde definimos nossas funções públicas;

Variáveis

Vamos começar criando uma a variável privada chamada owner que vai ser do tipo address, e uma variável pública chamada addressToBalance que vai ser do tipo mapping, essa variável recebe um address como chave e armazena um uint como valor.
O mapping é usado ​​para armazenar dados na forma de pares chave-valor, a chave pode ser qualquer um dos tipos de dados do solidity. mapping parece muito com um objeto, onde você pode criar uma chave e definir um valor para ele.

    //Properties
    address private owner;
    mapping(address => uint) public addressToBalance;
Enter fullscreen mode Exit fullscreen mode

Caso queira entender um pouco mais sobre os tipos de dados que exite no solidity clique aqui

Modificadores

O modifier é usado ​​para modificar o comportamento de uma função.
Por exemplo, vamos criar um modifier chamado isOwner que dentro dele vai ter um require, que basicamente vai exigir que o msg.sender (já vamos ver o que é isso) seja igual o endereço do dono do contrato (owner).

    //Modifiers
    modifier isOwner() {
        require(msg.sender == owner , "Sender is not owner!");
        _; // {1}
    }
Enter fullscreen mode Exit fullscreen mode

Na linha {1} se a instrução require retornar um true então será executado o código _; que significa: execute o que vem depois.
Isso quer dizer que se o código quebrar no require não irá executar a instrução, logo, não irá executar o código da função que vem depois.

Eventos

Agora vamos criar os eventos BalanceIncreased passando como
parâmetros target que vai ser do tipo address e balance que vai ser do tipo uint256, que vai ser chamado quando depositamos uma quantidade de "dinheiro" para um endereço.
E no OwnerChanged vamos passar como parâmetros oldOwner que vai ser do tipo address e newOwner que também vai ser do tipo address, que vai ser chamado quando mudarmos o dono do nosso contrato.
Quando um event é emitido ele armazena os argumentos passados e realiza uma ação.
Um evento gerado não é acessível dentro dos contratos, nem mesmo aqueles que os criou ou chamou. Os eventos no solidity servem para enviarmos alguma resposta para o nosso front-end, por exemplo depois que acontecer alguma ação no contrato.

  //Events
    event BalanceIncreased(address target, uint256 balance);
    event OwnerChanged(address oldOwner, address newOwner);
Enter fullscreen mode Exit fullscreen mode

Construtor

Vamos agora criar o nosso construtor, que vai definir que o owner vai receber o msg.sender, resumidamente o msg.sender é sempre o endereço de quem chamou a função. Nesse caso estamos definindo que quem fez o deploy do contrato vai ser o owner do contrato.

Caso queira entender um pouco mais sobre msg.sender clique aqui

   //Constructor
    constructor() {
        owner = msg.sender;
    }
Enter fullscreen mode Exit fullscreen mode

Funções

Adicionar saldo à um endereço

Vamos criar uma função pública chamada addBalance que vai nos permitir adicionar uma quantia de "dinheiro" há uma conta. Para conseguirmos fazer isso addBalance irá ter alguns parâmetros como to que vai ser do tipo address e value que vai ser do tipo uint.

  //Public functions
    function addBalance(address to, uint value) public {

    }
Enter fullscreen mode Exit fullscreen mode

E por questão de segurança queremos que somente o dono (owner) do contrato possa adicionar "dinheiro" há um endereço. Para isso vamos colocar na frente da nossa função o nosso modificador isOwner, assim antes de executar nossa função ele vai executar o nosso modificador isOwner e verificar se quem está chamando a função é o owner, se não for vai retornar uma mensagem de erro.

  //Public functions
     function addBalance(address to, uint value) public isOwner {

    }
Enter fullscreen mode Exit fullscreen mode

Dentro da nossa função addBalance vamos escrever a lógica para adicionar uma quantidade de "dinheiro" há uma conta.
Usando o nosso mapping addressToBalance vamos pegar a quantidade de "dinheiro" do endereço do parâmetro to e adicionamos uma quantidade de "dinheiro" que vamos passar no parâmetro value, depois vamos chamar o evento BalanceIncreased passando como parâmetros o endereço (to) e a quantidade (value) de "dinheiro" que queremos enviar.

//Public functions
    function addBalance(address to, uint value) public isOwner {
        addressToBalance[address(to)] = addressToBalance[address(to)] + value;
        emit BalanceIncreased(to, value);
    }
Enter fullscreen mode Exit fullscreen mode

Alterando dono do contrato

As regras da nossa função para trocar o dono do contrato é bem parecida com a da função addBalance.
Vamos criar uma função pública chamada changeOwner que somente o dono do contrato (owner) vai conseguir chamar essa função, que seja possível passar um endereço (newOwnerContract) como parâmetro.

    function changeOwner(address newOwnerContract) public isOwner{

    }
Enter fullscreen mode Exit fullscreen mode

Dentro da nossa função changeOwner vamos redefinir o valor da variável owner para o endereço do novo dono (newOwnerContract), e chamar nosso evento OwnerChanged passando o endereço do atual dono (owner) do contrato e o endereço do novo dono (newOwnerContract) como parâmetros.

    function changeOwner(address newOwnerContract) public isOwner{
        owner = newOwnerContract;
        emit OwnerChanged(owner, newOwnerContract);
    }
Enter fullscreen mode Exit fullscreen mode

Como ficou nosso código

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Bank {

    //Properties
    address private owner;
    mapping(address => uint) public addressToBalance;

    //Modifiers
    modifier isOwner() {
        require(msg.sender == owner , "Sender is not owner!");
        _;
    }

    //Events
    event BalanceIncreased(address target, uint256 balance);
    event OwnerChanged(address oldOwner, address newOwner);

    //Constructor
    constructor() {
        owner = msg.sender;
    }

    //Public functions
    function addBalance(address to, uint value) public isOwner {
        addressToBalance[address(to)] = addressToBalance[address(to)] + value;
        emit BalanceIncreased(to, value);
    }

    function changeOwner(address newOwnerContract) public isOwner{
        owner = newOwnerContract;
        emit OwnerChanged(owner, newOwnerContract);
    }
}
Enter fullscreen mode Exit fullscreen mode

Mão na massa

Agora vamos compilar e realizar o deploy do nosso contrato 01-bank.sol.

  1. No menu lateral esquerdo clique em "Solidity compiler".
    Abrindo aba para compilar o contrato

  2. Clique no botão "Compile 01-bank.sol".
    Compilando o contrato 01-bank.sol

  3. No menu lateral esquerdo clique em "Deploy & run transactions".
    Abrindo aba para fazer o deploy

  4. Clique no botão "Deploy".
    Fazendo o deploy do contrato 01-bank.sol

  5. Clique na seta para vermos as funções do nosso contrato.
    Abrindo contrato que fizemos deploy

  6. Copie o endereço da carteira que fizemos o deploy.
    copiando endereço da carteira

  7. Clique em "addressToBalance" para verificar o salto do endereço que passamos.
    Utilizando a função addressToBalance do contrato 01-bank.sol

  8. Podemos ver que o saldo do nosso endereço está zerado.
    Verificando saldo

  9. Clique na seta para vermos todos os campos da função.
    Vendo todos os campos da função addBalance

  10. Copie o endereço da nossa carteira novamente.
    copiando endereço da nossa carteira

  11. Informe o endereço da nossa carteira no primeiro campo e informe a quantidade de "dinheiro" que quer depositar.
    Utilizando a função addBalance

  12. Clique em "addressToBalance" para verificar o salto do endereço após o depósito do "dinheiro".
    Utilizando a função addressToBalance do contrato 01-bank.sol após depósito

  13. Podemos ver que o saldo do nosso endereço tem a mesma quantidade de "dinheiro" que passamos na função addBalance.
    Verificando saldo depois de execultar a função addBalance

  14. Agora vamos pegar o endereço de outra carteira, para isso só clica em cima do endereço que irá aparecer uma lista de endereços.
    Mudando de endereço

  15. Copie o endereço dessa nova carteira.
    Copiando endereço da nova carteira

  16. Agora vamos voltar para o endereço da primeira carteira, e informe o endereço da carteira do owner (a carteira que utilizamos para fazer o deploy) e clique na função "changeOwner".
    Utilizando a função changeOwner

  17. Se tudo estiver certo quando clicarmos para executar novamente a função "changeOwner" vai dar um erro no console.
    Erro no console

Conclusão

Esse foi o segundo post da série de posts "Meu primeiro smart contract".
Se você realizou todas as etapas acima, agora você tem um smart contract simples de um banco, onde você consegue depositar uma quantia de "dinheiro" e mudar o dono do contrato.

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/

Top comments (1)

Collapse
 
claudiomouraneto profile image
Claudio Moura Neto

Legal também mencionar que colocando o primeiro endereço (do owner original que criou o contrato) a função changeOwner funciona.. ;)