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);
}
}
}
}
输出 :