区块链 以太坊 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 以及如何在以太坊区块链上开发 Dapps,我的理解是不是正确?
区块链项目实战 - 使用以太坊/智能合约solidity,全栈开发区块链借贷记账小应用,含完整源码