solidity的函数修改器(modifier)
内容:modifier的定义、modifier对函数参数的操作、modifier执行的顺序
modifier的定义
官方文档:modifier可以改变函数的行为。可以被继承和重写。
其实modifier被用于最多的是行为检查,这样可以使得减少检查代码的复用以及让代码看起来更简介易懂。比如,检查调用者是否有权限执行这个函数,传入的参数是否有错误等等。但是modifier不仅仅于此。通过一下一个例子来熟悉了解一下modifier的用法:
// 建立了一个NoteBook的合约,只有NoteBook的拥有者才可以修改其内容record
contract NoteBook{
string public record; // NoteBook的内容
address owner; // NoteBook的拥有者
constructor() {
owner = msg.sender;
}
// 修改record的内容
function changeRecord(string memory _record) public isOwner {
record = _record;
}
// 函数修改器:判断是否是NoteBook的
modifier isOwner{
require(msg.sender == owner, "You are not the owner of this NoteBook");
_;
}
}
上述例子中,我们通过关键字 modifier
后面接函数修改器名 NoteBook
来定义一个modifier。在上述定义的modifier中如果调用者不是拥有者则会停止执行接下来的代码,并在控制台输出自定义的原因。如果是的话则执行到 _
处,_
代表使用该modifier的函数体,这里即为changeRecord
函数的函数体。在执行changeRecord
函数前先会使用isOwner进行检查,没有问题后才会执行。
modifier对函数参数的操作
执行函数时有时候也会对函数的参数有所要求,为了让函数内的代码更简洁我们便可以写在modifier中。那如何对函数参数进行检查呢?这个和函数的操作一样,调用时传参便可。看如下例子:
// 这个合约可以执行运算
contract Operation{
// 除法运算
function division(uint256 opt1, uint256 opt2) public checkZero(opt2) pure returns(uint256){
return opt1 / opt2;
}
// 检查除数是否为0
modifier checkZero(uint256 divisor) {
require (divisor != 0, "divisor can't be 0");
_;
}
}
在以上代码中我们需要做的是检查除法运算中的除数是否为0,若是0则中止运行,并给予提示。代码简单就不啰嗦了。
当然modifier还可以对storage中的变量进行检查,
modifier的执行顺序
一个函数可能需要做多个检查,那么我们可以写多个modifier,调用时只需将每个modifier以空格隔开。而检查顺序也就是modifier们的排列顺序。
但还有一种可能会迷惑大家的写法:
contract modifierOder {
address owner;
uint256 a;
constructor() {
owner = msg.sender;
}
function test(uint num) public checkPara(num) returns(uint256) {
a = 10;
return a;
}
// 修改a
modifier checkPara(uint number) {
a = 1;
_;
a = 100;
}
}
如以上代码所示:在 _
后又有一句代码a = 100
。函数执行完return
后,后面的代码则不再执行,但是在modifier中,执行完函数体 _
还会接着执行 a = 100
这条语句。所以尽管函数返回的a
的值为10,但是最后a
的值变成了100。
以上所有代码都是给予solidity 0.7.x的编译器
以上就是所有内容的,有不妥之处,敬请大家指正。
参考链接:
https://me.tryblockchain.org/blockchain-solidity-functionModifier.html
https://learnblockchain.cn/docs/solidity/contracts.html#modifiers
最新文章
- 使用border做三角形
- [C#]浅析ref、out参数
- angular之控制器(0)
- Hibernate day01笔记
- Jquery easyui中的有效性检查
- Magento在IE下登陆不了后台,在Firefox下正常
- kali linux 一些工具及命令集1(搜集DNS信息)
- SRM 511 DIV1 500pt(DP)
- python 进制 转换
- spring security 跨域防伪攻击
- cpp - 输入输出
- LeetCode Javascript实现 344. Reverse String 292. Nim Game 371. Sum of Two Integers
- Dockerfile封装Django镜像
- Confluence 6 其他需要备份和恢复的地方
- Python操纵Excel,数据库
- 从html页面中抽取table表格数据
- Red Hat6设置使用CentOS的yum源
- C/C++.全文件名全路径名分割拆分分解
- MySQL——SQL Mode详解
- 9款赏心悦目的HTML5/CSS3应用特效
热门文章
- 【Spring】Spring的数据库开发 - 2、Spring JdbcTemplate的常用方法(execute、update、query)
- 用percona monitoring plugins 监控mysql
- dmp文件导入抽取方法
- k8s集群中遇到etcd集群故障的排查思路
- JVM 判断对象已死,实践验证GC回收
- 创建并使用https证书
- JavaSE 基础知识(常识概念 + 基础语法)问答总结/面试题 —— 讲给应届生的 Java 开源知识项目
- qt for webassembly环境搭建图文教程
- DSL是什么?Elasticsearch的Query DSL又是什么?
- U盘制作系统启动盘方法