区块链 以太坊 solidity require revert assert
  DJsdk34H4Gbu 2023年11月02日 83 0


在编写智能合约时,一定要注意对合约参数和行为的检查,尤其是那些对外部开放的合约函数。

Solidity提供了require、revert、assert等关键字来进行异常的检测和处理。

一旦检测并发现错误,整个函数调用会被回滚,所有状态修改都会被回退,就像从未调用过函数一样。

以下分别使用了三个关键字,实现了相同的语义。

require(_data == data, "require data is valid");

if(_data != data) { revert("require data is valid"); }

assert(_data == data);

不过,这三个关键字一般适用于不同的使用场景:

  • require:最常用的检测关键字,用来验证输入参数和调用函数结果是否合法。

  • revert:适用在某个分支判断的场景下。

  • assert: 检查结果是否正确、合法,一般用于函数结尾。

在一个合约的函数中,可以使用函数修饰器来抽象部分参数和条件的检查。

在函数体内,可以对运行状态使用if-else等判断语句进行检查,对异常的分支使用revert回退。

在函数运行结束前,可以使用assert对执行结果或中间状态进行断言检查。

在实践中,推荐使用require关键字,并将条件检查移到函数修饰器中去;这样可以让函数的职责更为单一,更专注到业务逻辑中。同时,函数修饰器等条件代码也更容易被复用,合约也会更加安全、层次化。

在本文中,我们以一个水果店库存管理系统为例,设计一个水果超市的合约。这个合约只包含了对店内所有水果品类和库存数量的管理,setFruitStock函数提供了对应水果库存设置的函数。在这个合约中,我们需要检查传入的参数,即水果名称不能为空。

pragma solidity ^0.4.25;

contract FruitStore {
mapping(bytes => uint) _fruitStock;
modifier validFruitName(bytes fruitName) {
require(fruitName.length > 0, "fruite name is invalid!");
_;
}
function setFruitStock(bytes fruitName, uint stock) validFruitName(fruitName) external {
_fruitStock[fruitName] = stock;
}
}

如上所述,我们添加了函数执行前的参数检查的函数修饰器。同理,通过使用函数执行前和函数执行后检查的函数修饰器,可以保证智能合约更加安全、清晰。智能合约的编写需要设置严格的前置和后置函数检查,来保证其安全性。


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
DJsdk34H4Gbu