SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
02.12.2024

Aula 206: Chamadas e Interação entre Contratos

No mundo dos contratos inteligentes da Ethereum, muitas vezes é necessário que um contrato interaja com outro. Esta aula explorará as chamadas entre contratos e como implementá-las corretamente em Solidity. Compreender essas interações é crucial para construir aplicações descentralizadas (dApps) complexas.

Visão Geral das Chamadas entre Contratos

As chamadas entre contratos permitem que um contrato inteligente invoque funções de outro contrato inteligente. Isso pode ser benéfico por várias razões, como compor diferentes contratos para criar um sistema mais complexo, compartilhar lógica ou distribuir funcionalidades entre múltiplos contratos.

Exemplo Básico de Chamadas entre Contratos

Vamos considerar um cenário simples em que temos dois contratos: ContratoA e ContratoB. ContratoA chamará uma função em ContratoB.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract ContratoB {
    uint public valor;

    function definirValor(uint _valor) public {
        valor = _valor;
    }

    function obterValor() public view returns (uint) {
        return valor;
    }
}

contract ContratoA {
    ContratoB public contratoB;

    constructor(address _enderecoContratoB) {
        contratoB = ContratoB(_enderecoContratoB);
    }

    function atualizarValorEmB(uint _novoValor) public {
        contratoB.definirValor(_novoValor);
    }

    function obterValorDeB() public view returns (uint) {
        return contratoB.obterValor();
    }
}

Explicação do Exemplo

  1. ContratoB:

    • Contém uma variável de estado valor.
    • Possui a função definirValor que atualiza o estado.
    • Possui a função obterValor que recupera o valor atual.
  2. ContratoA:

    • Mantém uma referência a ContratoB.
    • Fornece um construtor que recebe o endereço de um ContratoB já implantado e o armazena.
    • Possui a função atualizarValorEmB que chama definirValor na instância de ContratoB.
    • Fornece a função obterValorDeB para buscar o valor de ContratoB.

Implantando e Interagindo com os Contratos

Para implantar e interagir com esses contratos, siga os seguintes passos:

  1. Implantar ContratoB: Implemente ContratoB primeiro na rede Ethereum.
  2. Obter Endereço de ContratoB: Após a implantação, anote o endereço do contrato.
  3. Implantar ContratoA: Passe o endereço de ContratoB para o construtor de ContratoA durante a implantação.
  4. Atualizar Valor: Chame atualizarValorEmB em ContratoA para modificar o estado em ContratoB.
  5. Buscar Valor: Chame obterValorDeB em ContratoA para recuperar o valor atualizado de ContratoB.

Tratamento de Erros em Chamadas entre Contratos

É importante lidar com possíveis falhas ao fazer chamadas entre contratos. Um padrão comum é garantir que a função chamada retorne um indicador de sucesso ou utilize declarações require para validar o estado. Aqui está um exemplo que mostra um mecanismo básico de verificação de erros:

function atualizarValorEmB(uint _novoValor) public {
    // Chame a função definirValor em ContratoB e verifique o sucesso
    (bool sucesso, ) = address(contratoB).call(abi.encodeWithSignature("definirValor(uint256)", _novoValor));
    require(sucesso, "Falha ao atualizar valor em ContratoB");
}

Usando Eventos para Melhor Rastreabilidade

Ao interagir entre contratos, eventos fornecem um mecanismo valioso para rastrear mudanças de estado. Você pode emitir eventos em ambos os contratos para registrar as atualizações:

contract ContratoB {
    event ValorAtualizado(uint novoValor);

    //... outras funções

    function definirValor(uint _valor) public {
        valor = _valor;
        emit ValorAtualizado(_valor);
    }
}

contract ContratoA {
    event ValorChamadoDeB(uint valor);

    function obterValorDeB() public view returns (uint) {
        uint val = contratoB.obterValor();
        emit ValorChamadoDeB(val);
        return val;
    }
}

Conclusão

As interações entre contratos são um recurso poderoso do Solidity que permite aos desenvolvedores criar aplicações mais complexas e modulares. Com um planejamento cuidadoso em relação às dependências dos contratos, o tratamento de erros e a emissão de eventos, você pode construir aplicações descentralizadas robustas. Nas próximas aulas, podemos cobrir padrões avançados, como proxies e contratos atualizáveis, que muitas vezes dependem fortemente de interações entre múltiplos contratos.

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!