区块链 以太坊 solidity require revert assert

Posted 软件工程小施同学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链 以太坊 solidity require revert assert相关的知识,希望对你有一定的参考价值。

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

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;    }}

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

以上是关于区块链 以太坊 solidity require revert assert的主要内容,如果未能解决你的问题,请参考以下文章

区块链 solidity 零知识证明DApp开发实践身份证明/以太坊

以太坊区块链 Solidity solc是什么

我目前正在学习 Solidity 以及如何在以太坊区块链上开发 Dapps,我的理解是不是正确?

区块链项目实战 - 使用以太坊/智能合约solidity,全栈开发区块链借贷记账小应用,含完整源码

区块链项目实战 - 使用以太坊/智能合约solidity,全栈开发区块链借贷记账小应用,含完整源码

区块链2.0以太坊智能合约solidity之helloworld