SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
18.11.2024

Lição: 064: Especificadores de Visibilidade em Profundidade

Em Solidity, os especificadores de visibilidade são essenciais para controlar como as funções e variáveis de estado podem ser acessadas, tanto internamente quanto externamente. Compreender esses especificadores é crucial para escrever contratos inteligentes seguros e eficientes.

Tipos de Especificadores de Visibilidade

Existem quatro principais especificadores de visibilidade em Solidity:

  1. public
  2. external
  3. internal
  4. private

Vamos explorar cada um deles em detalhe.

1. Public

Quando uma função ou variável de estado é declarada como public, ela pode ser acessada de qualquer lugar — tanto internamente (dentro do contrato e contratos derivados) quanto externamente (de outros contratos e transações).

Exemplo:

pragma solidity ^0.8.0;

contract ExemploPublico {
    uint256 public dados;

    function definirDados(uint256 _dados) public {
        dados = _dados;
    }
}

Neste exemplo, a variável dados e a função definirDados podem ser acessadas de fora do contrato.

2. External

O especificador external significa que uma função só pode ser chamada de fora do contrato. Isso inclui chamadas feitas por outros contratos ou usuários, mas não chamadas internas.

Exemplo:

pragma solidity ^0.8.0;

contract ExemploExterno {
    uint256 public numero;

    function definirNumero(uint256 _numero) external {
        numero = _numero;
    }

    // Isso causará um erro de compilação
    // function chamadaInterna() internal {
    //     definirNumero(10);
    // }
}

Neste exemplo, a função definirNumero pode ser chamada a partir de fontes externas, mas não pode ser chamada internamente dentro do contrato.

3. Internal

Quando uma função ou variável de estado é marcada como internal, ela só pode ser acessada de dentro do próprio contrato e de contratos derivados. Isso é útil para funções auxiliares que não devem ser expostas publicamente.

Exemplo:

pragma solidity ^0.8.0;

contract ExemploInterno {
    uint256 internal contador;

    function incrementar() internal {
        contador += 1;
    }
}

contract ContratoDerivado is ExemploInterno {
    function aumentarContador() public {
        incrementar(); // Acessando função interna
    }

    function obterContador() public view returns (uint256) {
        return contador; // Acessando variável interna
    }
}

Neste caso, a função incrementar e a variável contador são acessíveis dentro do ContratoDerivado, mas não estão disponíveis para o público.

4. Private

O especificador private restringe o acesso apenas ao contrato que a declarou. Este é o nível de visibilidade mais restritivo.

Exemplo:

pragma solidity ^0.8.0;

contract ExemploPrivado {
    uint256 private numeroSecreto;

    function definirNumeroSecreto(uint256 _numero) public {
        numeroSecreto = _numero;
    }

    function obterNumeroSecreto() public view returns (uint256) {
        return numeroSecreto;
    }
}

contract OutroContrato {
    // Isso causará um erro de compilação
    // function acessarVariavelPrivada(ExemploPrivado _contrato) public view returns (uint256) {
    //     return _contrato.numeroSecreto;
    // }
}

Neste exemplo, numeroSecreto é privado e não pode ser acessado pelo OutroContrato. Ele só pode ser interagido através das funções públicas em ExemploPrivado.

Resumo

Escolher o especificador de visibilidade apropriado é vital para a segurança e clareza do contrato. Aqui está um breve resumo:

  • public: Acessível de dentro e fora do contrato.
  • external: Acessível apenas de fora do contrato.
  • internal: Acessível apenas dentro do contrato e contratos derivados.
  • private: Acessível apenas dentro do contrato que o declarou.

Utilizar esses modificadores de forma apropriada permite uma melhor encapsulação e segurança em seus contratos inteligentes, reduzindo o risco de interações indesejadas.

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

Thank you for voting!