Lição: 021: Modificadores de Função em Solidity
Em Solidity, os modificadores de função são um recurso poderoso que permite alterar o comportamento das funções de maneira reutilizável. Eles são frequentemente utilizados para controle de acesso, validação e outras pré ou pós-condições que uma função deve atender antes de ser executada.
O que são Modificadores de Função?
Um modificador de função é um bloco de código que pode ser usado para modificar o comportamento de uma função. Modificadores podem ser aplicados a funções e são definidos usando a palavra-chave modifier
. Eles podem receber parâmetros e um dos seus principais usos é adicionar pré-condições ou verificações antes que a função seja executada.
Sintaxe Básica
Aqui está a sintaxe básica de um modificador de função:
modifier nomeDoModificador() {
// código que é executado antes da função
_;
// código que é executado depois da função (opcional)
}
O underscore (_
) é um marcador que indica onde o corpo da função modificada será inserido.
Exemplo Simples
Vamos passar por um exemplo simples que ilustra como usar modificadores de função.
Exemplo 1: Modificador de Controle de Acesso
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contrato Proprietario {
endereço público dono;
constructor() {
dono = msg.sender; // Define o criador do contrato como o dono
}
modifier apenasDono() {
require(msg.sender == dono, "Você não é o dono");
_; // Prossegue para a função modificada
}
função mudarDono(endereço novoDono) público apenasDono {
dono = novoDono;
}
}
Neste exemplo, criamos um contrato simples Proprietario
que permite apenas ao dono mudar a propriedade. O modificador apenasDono
verifica se o remetente da transação (msg.sender
) é o dono. Caso contrário, ele reverte a transação com uma mensagem de erro. O underscore _
indica onde o código da função será inserido.
Exemplo 2: Modificador de Validação
Você também pode usar modificadores para validar parâmetros de entrada.
contrato Banco {
mapeamento(endereço => uint) público saldos;
modifier temSaldo(uint valor) {
require(saldos[msg.sender] >= valor, "Saldo insuficiente");
_;
}
função depositar() público pagável {
saldos[msg.sender] += msg.value;
}
função retirar(uint valor) público temSaldo(valor) {
saldos[msg.sender] -= valor;
pagável(msg.sender).transfer(valor);
}
}
Neste contrato Banco
, temos um modificador temSaldo
que verifica se o chamador possui saldo suficiente antes de permitir a retirada de fundos. Se o chamador não atender ao requisito, a transação será revertida com uma mensagem de erro.
Exemplo 3: Múltiplos Modificadores
Você também pode aplicar múltiplos modificadores a uma única função.
contrato Eleições {
estrutura Candidato {
string nome;
uint contagemVotos;
}
mapeamento(endereço => bool) público eleitores;
Candidato[] público candidatos;
modifier naoVotou() {
require(!eleitores[msg.sender], "Você já votou");
_;
}
modifier candidatoValido(uint indiceCandidato) {
require(indiceCandidato < candidatos.length, "Índice do candidato inválido");
_;
}
função adicionarCandidato(string memória nome) público {
candidatos.push(Candidato(nome, 0));
}
função votar(uint indiceCandidato) público naoVotou candidatoValido(indiceCandidato) {
eleitores[msg.sender] = true;
candidatos[indiceCandidato].contagemVotos += 1;
}
}
No contrato Eleições
, definimos dois modificadores: naoVotou
para verificar se o eleitor já votou e candidatoValido
para garantir que o índice do candidato fornecido seja válido. A função votar
usa ambos os modificadores para impor esses requisitos.
Conclusão
Os modificadores de função em Solidity são uma excelente forma de encapsular e reutilizar lógica que pode ser aplicada em múltiplas funções. Eles ajudam a melhorar a legibilidade e a manutenibilidade do código, ao mesmo tempo em que impõem regras e condições. Ao entender e utilizar modificadores de forma eficaz, você pode escrever contratos inteligentes mais seguros e robustos.
Sinta-se à vontade para explorar casos de uso mais complexos e implementar seus próprios modificadores enquanto continua aprendendo Solidity!