SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
26.11.2024

Lição: 144: Padrão Checagens-Effectos-Interações

No mundo dos contratos inteligentes do Ethereum, a segurança é fundamental. Um dos padrões de design mais recomendados para aumentar a segurança nos seus contratos em Solidity é o padrão Checagens-Effectos-Interações. Este padrão ajuda a prevenir ataques de reentrância, que podem resultar em vulnerabilidades graves no seu contrato inteligente.

Visão Geral

O padrão Checagens-Effectos-Interações é uma metodologia de design que enfatiza a ordem das operações em um contrato inteligente para garantir que as mudanças de estado (efeitos) sejam feitas antes de interagir com contratos externos. O fluxo geral pode ser dividido em três etapas principais:

  1. Checagens: Valide as condições que precisam ser atendidas (como garantir saldo suficiente).
  2. Efeitos: Atualize o estado do contrato (como transferir tokens).
  3. Interações: Interaja com contratos externos (como chamar outro contrato ou transferir Ether).

Essa ordem garante que nenhuma interação externa possa manipular o estado do contrato de forma inesperada.

Exemplo

Vamos ver um contrato de exemplo que implementa o padrão Checagens-Effectos-Interações. Criaremos um contrato de escrow simples que demonstra os princípios desse padrão.

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

contract Escrow {
    address public comprador;
    address public vendedor;
    uint256 public preco;
    bool public itemEntregue;

    // Eventos para registro
    event PagamentoRealizado(address indexed comprador, uint256 valor);
    event ItemEntregue(address indexed vendedor);
    event Retirado(address indexed vendedor);

    constructor(address _vendedor, uint256 _preco) {
        comprador = msg.sender;
        vendedor = _vendedor;
        preco = _preco;
    }

    function realizarPagamento() external payable {
        // Checagem: Garantir que o valor do pagamento está correto
        require(msg.value == preco, "Valor do pagamento incorreto");

        // Efeito: Mudar o estado do contrato para refletir que o pagamento foi realizado
        // Você pode querer adicionar mais atualizações de variáveis de estado aqui em um cenário real

        emit PagamentoRealizado(msg.sender, msg.value);
    }

    function confirmarEntrega() external {
        // Checagem: Garantir que apenas o vendedor pode confirmar a entrega
        require(msg.sender == vendedor, "Apenas o vendedor pode confirmar a entrega");

        // Efeito: Atualizar o estado de entrega do item
        itemEntregue = true;

        emit ItemEntregue(vendedor);
    }

    function retirar() external {
        // Checagem: Garantir que o vendedor só pode retirar se o item estiver entregue
        require(msg.sender == vendedor, "Apenas o vendedor pode retirar");
        require(itemEntregue, "O item deve ser entregue antes da retirada");

        // Efeito: Marcar entrega do item e transferir os fundos
        itemEntregue = false; // Redefinir estado para prevenir retirada dupla
        uint256 valor = address(this).balance;

        // Interação: Transferir fundos para o vendedor
        (bool sucesso, ) = vendedor.call{value: valor}("");
        require(sucesso, "Transferência falhou");

        emit Retirado(vendedor);
    }
}

Explicação do Exemplo

  1. Checagens:

    • Em realizarPagamento(), checamos se o valor do pagamento está correto.
    • Em confirmarEntrega(), garantimos que apenas o vendedor pode confirmar a entrega.
    • Em retirar(), verificamos que o vendedor só pode retirar se o item estiver entregue.
  2. Efeitos:

    • Em realizarPagamento(), este exemplo não muda o estado, além de registrar o evento, mas em uma aplicação real, você pode querer registrar o status do pagamento.
    • Em confirmarEntrega(), atualizamos o estado itemEntregue para true.
    • Em retirar(), definimos itemEntregue de volta para false para garantir um estado válido para operações futuras.
  3. Interações:

    • A interação real com uma conta externa ocorre na função retirar() ao transferir Ether para o vendedor.

Conclusão

O padrão Checagens-Effectos-Interações é um princípio fundamental para garantir a segurança e a confiabilidade dos seus contratos inteligentes. Ao seguir esse padrão, você mitiga o risco de ataques de reentrância e garante que seus contratos se comportem conforme o esperado, mesmo quando interagem com outros contratos ou usuários.

Sempre lembre-se de pensar criticamente sobre o fluxo do seu contrato inteligente para evitar vulnerabilidades que podem levar a perdas financeiras ou explorabilidade. Boa codificação!

Video

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

Thank you for voting!