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:
- public
- external
- internal
- 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.