📜  Solidity – 错误处理

📅  最后修改于: 2022-05-13 01:55:41.674000             🧑  作者: Mango

Solidity – 错误处理

Solidity 有许多用于错误处理的功能。错误可能发生在编译时或运行时。 Solidity 被编译为字节码,并在编译时进行语法错误检查,而运行时错误则难以捕捉,主要发生在执行合约时。一些运行时错误是气体不足错误、数据类型溢出错误、除以零错误、数组超出索引错误等。在 4.10 版之前,只有一个 throw 语句可以稳定地处理错误,所以要处理多个 if…else 语句的错误,必须实现检查值并抛出消耗更多 gas 的错误。在 4.10 版之后,引入了新的错误处理构造assert、require、revert语句,并且 throw 是绝对的。

要求声明

“require”语句声明了运行函数的先决条件,即它声明了在执行代码之前应该满足的约束。它接受单个参数并在评估后返回一个布尔值,它还有一个自定义字符串消息选项。如果为 false,则引发异常并终止执行。未使用的气体返回给调用者,状态恢复到其原始状态。以下是触发需要类型异常的一些情况:

  • 当使用结果为假的参数调用 require() 时。
  • 当消息调用的函数没有正确结束时。
  • 当使用 new 关键字创建合同并且流程未正确结束时。
  • 当无代码合约针对外部函数时。
  • 当使用公共 getter 方法将以太币发送到合约时。
  • 当 .transfer() 方法失败时。
    • 当使用导致错误的条件调用断言时。
    • 当调用函数的零初始化变量时。
    • 将大值或负值转换为枚举时。
    • 当一个值被零除或取模时。
    • 访问索引中的数组时太大或负数。

示例:在下面的示例中,合同 requireStatement演示了如何使用“require statement”。

Solidity
// Solidity program to demonstrate require statement
pragma solidity ^0.5.0;
 
// Creating a contract
contract requireStatement {
    
    // Defining function to check input
    function checkInput(uint _input) public view returns(string memory){
        require(_input >= 0, "invalid uint8");
        require(_input <= 255, "invalid uint8");
         
        return "Input is Uint8";
    }
    
    // Defining function to use require statement
    function Odd(uint _input) public view returns(bool){
        require(_input % 2 != 0);
        return true;
    }
}


Solidity
// Solidity program to demonstrate assert statement
pragma solidity ^0.5.0;
 
// Creating a contract
contract assertStatement {
   
    // Defining a state variable 
    bool result;
 
    // Defining a function to check condition
    function checkOverflow(uint _num1, uint _num2) public {
        uint sum = _num1 + _num2;
        assert(sum<=255);
        result = true;
    }
    
    // Defining a function to print result of assert statement
    function getResult() public view returns(string memory){
         if(result == true){
             return "No Overflow";
         }
         else{
             return "Overflow exist";
         }
    }
}


Solidity
// Solidity program to demonstrate revert statement
pragma solidity ^0.5.0;
 
// Creating a contract
contract revertStatement {
   
   // Defining a function to check condition
   function checkOverflow(uint _num1, uint _num2) public view returns(string memory, uint){
        uint sum = _num1 + _num2;
         if(sum < 0 || sum > 255){
             revert(" Overflow Exist");
         }
         else{
             return ("No Overflow", sum);
         }
          
    }
     
}
     
}


输出 :

要求声明

断言声明

它的语法类似于 require 语句。它在评估条件后返回一个布尔值。根据返回值,程序要么继续执行,要么抛出异常。断言语句不会返回未使用的气体,而是消耗整个气体供应,然后将状态反转到原始状态。 Assert 用于在合约执行前检查当前状态和函数条件。以下是一些带有断言类型异常的情况:

  • 当使用导致错误的条件调用断言时。
  • 当调用函数的零初始化变量时。
  • 将大值或负值转换为枚举时。
  • 当一个值被零除或取模时。
  • 访问索引中的数组时太大或负数。

示例:在下面的示例中,合约断言语句演示了如何使用“断言语句”。

坚固性

// Solidity program to demonstrate assert statement
pragma solidity ^0.5.0;
 
// Creating a contract
contract assertStatement {
   
    // Defining a state variable 
    bool result;
 
    // Defining a function to check condition
    function checkOverflow(uint _num1, uint _num2) public {
        uint sum = _num1 + _num2;
        assert(sum<=255);
        result = true;
    }
    
    // Defining a function to print result of assert statement
    function getResult() public view returns(string memory){
         if(result == true){
             return "No Overflow";
         }
         else{
             return "Overflow exist";
         }
    }
}

输出 :

断言声明

还原语句

此语句类似于 require 语句。它不评估任何条件,也不依赖于任何状态或语句。它用于生成异常、显示错误和恢复函数调用。该语句包含一个字符串消息,指示与异常信息相关的问题。调用 revert 语句意味着抛出异常,返回未使用的气体,状态恢复到其原始状态。 Revert 用于处理与 require 句柄相同的异常类型,但逻辑稍微复杂一些。

示例:在下面的示例中,合同 revertStatement演示了“revert statement”。

坚固性

// Solidity program to demonstrate revert statement
pragma solidity ^0.5.0;
 
// Creating a contract
contract revertStatement {
   
   // Defining a function to check condition
   function checkOverflow(uint _num1, uint _num2) public view returns(string memory, uint){
        uint sum = _num1 + _num2;
         if(sum < 0 || sum > 255){
             revert(" Overflow Exist");
         }
         else{
             return ("No Overflow", sum);
         }
          
    }
     
}
     
}

输出 :

还原语句还原语句