在Solidity0.4.10之前,错误处理模式是以if...throw形式展现,普遍用于判断一个条件是否满足,如果不满足则中断运行,但触发throw后它会撤回所有的状态更改,消耗剩余的所有gas,所以这并不是一个好的操作。之后,assert(), require(), revert() 三个函数代替了if...throw的功能,对gas有了更好的处理,提高了合约代码的可读性,但区分它们可能会有点混乱。
实验目的
1.明白require(),assert(),revert()三者的区别与作用。
实验要求
1. 请查看示例1中的两个函数。ShouldBeEven:这个函数用了require语句来检查传入的参数值是奇数还是偶数。如果传入值为偶数,继续往下执行下一个语句,否则抛出异常。再看第二个函数ValidUint8。请你补充代码,也用require语句来检查传入的值的范围是否在uint8的范围内。
2. 请查看示例2中的代码,函数validUint8对传入的数值进行了加20的操作,最后返回一个Uint8类型的值。思考当你调用函数validUint8传入的值为236-255范围内的任意值时,最后函数的返回值会是多少?如果结果有误,请你用assert语句补充好代码,在整型溢出时抛出异常。
3. 请查看示例3中的代码,调用函数validUint8,分别传入三个数值-1,125,256。查看三个数值的返回结果。思考solidity中对异常处理的require(),assert(),revert()三者之间的区别以及使用情况。
以下是本次实验所使用到的测试代码,请使用remix编辑器完成该实验
示例1:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract requireContract {
function ShouldBeEven(uint _data) public pure returns(bool){
require(_data % 2 == 0);
return true;
}
function validUint8(int _data) public pure returns(int){
//请你按要求补充代码
return _data;
}
}
示例2:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract assertContract {
function vaildUint8(uint _data) public pure returns(uint8){
require(_data >= 0);
require(_data <= 255);
uint8 value = 20;
//请你按要求在这一行补充好代码
return uint8(value + _data);
}
}
示例3:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract revertContract {
function validUint8(int _data) public pure returns(int){
if(_data < 0 || _data > 255) {
revert();
}
return _data;
}
}
下面是本次实验所配套的视频教程: