Tratamento de erros no Solidity
Neste artigo, discutiremos os diferentes tipos de erros que podem ocorrer no Solidity e exploraremos as melhores práticas de tratamento de erros para evitar armadilhas e vulnerabilidades comuns.
Tratamento de erros de solidez
Solidity tem muitas funções para lidar com erros.
Um erro pode ocorrer em tempo de compilação ou durante o tempo de execução.
Uma verificação de erro de sintaxe é executada em tempo de compilação no Solidity, mas os erros de tempo de execução são difíceis de detectar e ocorrem principalmente durante a execução do contrato.
Erros de falta de gás, tipos de dados de estouro, erros de divisão por zero, erros de matriz fora do índice, etc., são alguns dos erros de tempo de execução.
O Solidity tinha uma única instrução throw até a versão 4.10. Para lidar com erros, várias instruções if…else devem ser implementadas para verificar os valores e gerar erros.
Novas construções de tratamento de erros assert, require e revert foram introduzidas após a versão 4.10.
Exigir declarações
Uma instrução require especifica as restrições que devem ser atendidas antes que o código possa ser executado.
A função leva apenas um argumento e após a conclusão do processo de avaliação, retorna um valor booleano .
Além disso, ele também tem a opção de enviar mensagens de string personalizadas. Há uma exceção gerada se a condição for falsa e a execução for encerrada como resultado.
Após a reversão do estado, o gás não utilizado é devolvido ao chamador e o estado é revertido ao estado original.
Aqui estão alguns exemplos de situações em que um tipo obrigatório de exceção é acionado:
- No caso em que require() é chamado com argumentos que resultam em resultados falsos .
- Nesse caso, uma função chamada por uma mensagem não termina corretamente quando a mensagem é chamada.
- É possível que quando novas palavras-chave são usadas para criar o contrato, o processo não termine corretamente.
- Quando um contrato sem código se refere a uma função externa.
- Usando o método getter público para enviar ethers para o contrato.
- Há um problema com o método .transfer() .
O exemplo dado mostra o funcionamento das instruções r equire de uma maneira mais fácil. A função abaixo da função print_Even_Only apenas imprime ou executa quando um número par é atribuído a ela.
Example:
Example:
É possível retornar o valor booleano, bem como uma mensagem de string usando a instrução require conforme mostrado abaixo:
Example:
declaração de declaração
Em termos de sintaxe, é semelhante à instrução “require”. Ao avaliar a condição, retorna um valor booleano.
Dependendo do valor de retorno, o programa continuará ou lançará uma exceção.
Como resultado da instrução assert, todo o suprimento de gás é consumido, fazendo com que o estado seja revertido de volta ao seu estado original, em vez de retornar o gás não utilizado.
Antes da execução do contrato, assert verifica o estado atual e as condições da função.
Alguns exemplos de tipos de exceção de declaração estão listados abaixo:
- Nesse caso, o assert é chamado com uma condição falsa .
- A variável inicializada com zero de uma função é chamada.
- Convertendo um valor grande ou negativo em uma enumeração ( enum ).
- Um valor é dividido ou módulo por zero.
- Quando uma matriz é acessada com um índice muito grande ou negativo.
O exemplo fornecido explicará o funcionamento básico da declaração de solidity assert.
Aqui, a entrada do usuário é correspondida apenas com o ample_number , então adiciona 50 à entrada do usuário, caso contrário, gera um erro:
Example:
A instrução assert é usada no exemplo abaixo para verificar se o valor digitado pelo usuário é maior que mrx , se for verdadeiro, imprime uma mensagem, caso contrário, mostra um erro:
Example:
Reverter declaração
Semelhante a uma instrução require, esta instrução retorna um valor.
A função não avalia nenhuma condição e não depende de nenhum estado ou declaração.
A função gera exceções, exibe erros e reverte a chamada.
A mensagem de cadeia nesta instrução indica o problema relacionado às informações de exceção.
Ao chamar uma instrução revert, o estado é retornado ao seu estado original, uma exceção é lançada e o gás não utilizado é retornado.
Revert lida com os mesmos tipos de exceções que exigem, mas com um pouco mais de complexidade.
O exemplo fornecido fornece o entendimento básico da instrução revert. O programa abaixo pega um número uint e verifica se é zero ou negativo. Se o resultado for verdadeiro, ele mostra uma exceção, senão imprime o número de acordo:
Example:
Da mesma forma, os outros exemplos mostram o funcionamento da instrução revert de maneira mais clara. O exemplo a seguir usa um inteiro como entrada do usuário avalia se o inteiro fornecido é completamente divisível por 5. Se o resultado for verdadeiro, ele imprime a mensagem, caso contrário, uma mensagem de erro é gerada:
Example:
Benefícios do tratamento de erros do Solidity
- O uso de instruções de tratamento de erros ajuda a evitar erros de contrato. Os desenvolvedores do Solidity podem evitar vulnerabilidades de segurança comuns, como ataques de reentrada e estouros de números inteiros, verificando entradas e condições de estado antes de executar o código.
- Explicar o que deu errado quando uma transação falha é crucial para melhorar a experiência do usuário. É possível fornecer aos usuários um feedback claro sobre o que deu errado, incluindo mensagens de erro informativas nas instruções de tratamento de erros.
- Consumo de gás reduzido: ao evitar cálculos desnecessários quando as entradas são inválidas ou as condições de estado não são atendidas, as declarações de tratamento de erros podem ajudar a reduzir o consumo de gás. É possível otimizar o desempenho do contrato e economizar nas tarifas de gás, revertendo uma transação assim que uma condição de erro for detectada.
- Depuração mais fácil: as mensagens de erro são úteis ao solucionar problemas de uma transação. Os desenvolvedores podem identificar e corrigir erros no código do contrato com mais facilidade se fornecerem mensagens de erro descritivas.
Conclusão
O tratamento de erros é um dos componentes mais críticos do desenvolvimento de contratos inteligentes Solidity.
Com o Solidity, você pode garantir que seus contratos sejam seguros, eficientes e fáceis de usar usando declarações de tratamento de erros, como require, assert e revert.
É possível para os desenvolvedores prevenir bugs e comportamentos inesperados, melhorar a experiência do usuário e reduzir o consumo de gás verificando entradas e condições de estado antes de executar o código, fornecendo mensagens de erro informativas e otimizando o desempenho do contrato.
O uso adequado de instruções de tratamento de erros permitirá que você crie contratos inteligentes mais confiáveis e seguros ao lidar com condições inesperadas e erros de entrada.