深入理解 Solidity 修饰符(Modifier):功能、应用与最佳实践
1. 什么是修饰符(Modifier)?
1.1 修饰符的定义
在 Solidity 中,修饰符(Modifier)是一种用于更改函数行为的关键字。它们可以用于控制函数的执行条件、添加前置检查、简化重复逻辑等。修饰符在函数执行之前执行一段代码,只有当修饰符的条件满足时,函数才会继续执行。修饰符的使用可以有效提高代码的可读性和可维护性。
1.2 修饰符的语法
修饰符的基本语法使用 modifier
关键字来声明,然后在修饰符中定义所需的逻辑。使用 _
表示函数主体将在修饰符逻辑执行后继续执行。
modifier onlyOwner() {require(msg.sender == owner, "Not the contract owner");_;
}
在上面的例子中,onlyOwner
修饰符确保只有合约的拥有者才能执行使用此修饰符的函数。_
表示修饰符通过检查后,函数的主体将继续执行。
2. 修饰符的应用场景
2.1 权限控制
修饰符最常见的应用场景是权限控制。例如,在一个去中心化应用(DApp)中,只有特定角色(如管理员或合约拥有者)可以执行某些敏感操作,如资金管理、合约升级等。
modifier onlyAdmin() {require(msg.sender == admin, "Not an admin");_;
}function updateSettings() public onlyAdmin {// 只有管理员可以调用该函数
}
通过使用 onlyAdmin
修饰符,我们可以确保只有 admin
地址能够调用 updateSettings
函数。
2.2 状态检查
修饰符还可以用于检查合约的状态,确保只有在合适的条件下才能执行某些操作。例如,防止在非活跃状态下执行某些函数。
modifier isActive() {require(active == true, "Contract is not active");_;
}function withdraw() public isActive {// 只有当合约处于活跃状态时,才能进行提现操作
}
在此例中,isActive
修饰符确保合约在活跃状态下执行 withdraw
函数。
2.3 输入参数验证
修饰符可以用于验证函数的输入参数。例如,检查传入的数值是否在合理范围内。
modifier validAmount(uint256 amount) {require(amount > 0, "Amount must be greater than zero");_;
}function deposit(uint256 amount) public validAmount(amount) {// 确保存款金额大于零
}
通过 validAmount
修饰符,我们可以防止无效的 amount
值进入函数逻辑。
3. 如何编写自定义修饰符?
3.1 编写基本修饰符
编写自定义修饰符时,通常会遵循以下步骤:
- 定义修饰符名称。
- 在修饰符内部编写条件检查逻辑。
- 使用
_
表示在检查通过后执行函数主体。
modifier onlyOwner() {require(msg.sender == owner, "You are not the owner");_;
}
3.2 带参数的修饰符
修饰符还可以接收参数,从而更加灵活地控制函数的行为。例如,下面的修饰符接收一个 address
参数,并检查调用者是否与指定地址匹配。
modifier onlyAddress(address _address) {require(msg.sender == _address, "Unauthorized address");_;
}function specialFunction(address _allowedAddress) public onlyAddress(_allowedAddress) {// 只有指定的地址可以调用此函数
}
带参数的修饰符允许我们在不同场景下灵活应用逻辑。
4. 多个修饰符的组合使用
4.1 修饰符的链式调用
Solidity 允许多个修饰符同时作用于一个函数。多个修饰符会按照从左到右的顺序依次执行。
modifier onlyOwner() {require(msg.sender == owner, "Not the owner");_;
}modifier isActive() {require(active == true, "Contract is not active");_;
}function closeContract() public onlyOwner isActive {// 合约只能由拥有者关闭,并且合约必须是活跃状态
}
在这个例子中,closeContract
函数要求调用者必须是合约拥有者,并且合约必须处于活跃状态。只有两个条件都满足时,函数主体才会执行。
4.2 修饰符的执行顺序
修饰符的执行顺序非常重要。多个修饰符会依次执行,并在通过所有条件后才执行函数主体。因此,修饰符的顺序直接影响函数的执行逻辑。
5. 修饰符在 Solidity 开发中的最佳实践
5.1 避免重复代码
修饰符可以有效避免代码的重复。例如,权限控制逻辑通常会在多个函数中使用,将这些逻辑抽象为修饰符可以减少代码重复,提高代码的可维护性。
modifier onlyOwner() {require(msg.sender == owner, "Not the contract owner");_;
}function setOwner(address newOwner) public onlyOwner {owner = newOwner;
}function withdrawFunds() public onlyOwner {// 只有拥有者才能提取资金
}
通过将权限检查逻辑抽象为 onlyOwner
修饰符,我们可以在多个函数中复用这一逻辑。
5.2 使用适当的错误信息
在修饰符中抛出异常时,应该使用简明清晰的错误信息。这可以帮助调用者快速了解问题所在,并便于调试。例如:
modifier onlyOwner() {require(msg.sender == owner, "You must be the contract owner to execute this function");_;
}
5.3 避免过多修饰符
尽管修饰符可以提高代码可读性,但过度使用修饰符可能会导致代码过于复杂,难以追踪函数的执行逻辑。因此,修饰符的数量应保持适中,并根据需要合理使用。
6. 修饰符与函数修饰符的区别
6.1 修饰符与函数修饰符
在 Solidity 中,除了自定义的修饰符外,函数修饰符(如 public
、private
、view
、pure
)也用于控制函数的可见性和行为。虽然它们的作用不同,但都可以改变函数的执行逻辑。
修饰符示例:
modifier onlyOwner() {require(msg.sender == owner, "Not the contract owner");_;
}function updateData() public onlyOwner {// 使用 onlyOwner 修饰符
}
函数修饰符示例:
function getBalance() public view returns (uint256) {// view 函数不会修改合约状态
}
修饰符侧重于检查条件和控制函数执行,而函数修饰符则定义了函数的行为(如是否修改状态)。
7. 结论
Solidity 中的修饰符是一种强大的工具,能够帮助开发者编写更加简洁、可读性高的代码。通过使用修饰符,可以有效地管理权限控制、状态检查、输入验证等逻辑。虽然修饰符具有许多优点,但开发者应注意不要过度使用,以免导致代码复杂化。在实际项目中,合理设计修饰符将为智能合约的开发带来更高的灵活性和安全性。
相关文章:
深入理解 Solidity 修饰符(Modifier):功能、应用与最佳实践
1. 什么是修饰符(Modifier)? 1.1 修饰符的定义 在 Solidity 中,修饰符(Modifier)是一种用于更改函数行为的关键字。它们可以用于控制函数的执行条件、添加前置检查、简化重复逻辑等。修饰符在函数执行之前…...
YOLO11项目实战1:道路缺陷检测系统设计【Python源码+数据集+运行演示】
一、项目背景 随着城市化进程的加速和交通网络的不断扩展,道路维护成为城市管理中的一个重要环节。道路缺陷(如裂缝、坑洞、路面破损等)不仅影响行车安全,还会增加车辆的磨损和维修成本。传统的道路缺陷检测方法主要依赖人工巡检…...
怎么屏蔽统计系统统计到的虚假ip
屏蔽统计系统中的虚假IP是保护网站分析数据准确性的重要措施。以下是一些有效的策略和步骤,可以帮助您过滤掉虚假IP: 1. 识别虚假IP的特征 了解虚假IP的常见特征可以帮助您识别和屏蔽它们: 短时间内高频率访问:虚假IP可能会在短…...
前端开发设计模式——策略模式
目录 一、策略模式的定义和特点 1.定义: 2.特点: 二、策略模式的实现方式 1.定义策略接口: 2.创建具体策略类: 3.定义上下文类: 三、策略模式的应用场景 1.表单验证场景: 2.动画效果切换场景&…...
SysML案例-潜艇
DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>>...
车辆重识别(2020NIPS去噪扩散概率模型)论文阅读2024/9/27
[2] Denoising Diffusion Probabilistic Models 作者:Jonathan Ho Ajay Jain Pieter Abbeel 单位:加州大学伯克利分校 摘要: 我们提出了高质量的图像合成结果使用扩散概率模型,一类潜变量模型从非平衡热力学的考虑启发。我们的最…...
基于深度学习的任务序列中的快速适应
基于深度学习的任务序列中的快速适应是指模型在接连处理不同任务时,能够迅速调整和优化自身以适应新任务的能力。这种能力在动态环境和多任务学习中尤为重要,旨在减少训练时间和资源需求。以下是这一主题的关键要素: 1. 快速适应的背景 动态…...
虚拟机三种网络模式详解
在电脑里开一台虚拟机,是再常见不过的操作了。无论是用虚拟机玩只有旧版本系统能运行的游戏,还是用来学习Linux、跑跑应用程序都是很好的。而这其中,虚拟机网络是绝对绕不过去的。本篇文章通俗易懂的介绍了常见的虚拟网络提供的三种网络链接模…...
[leetcode]674_最长连续递增序列
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。 连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l < i < r,都有 nums[i] < nums[i 1] &am…...
【无人机设计与技术】四旋翼无人机,UAV仿真,轨迹跟踪PID控制
摘要 本文探讨了四旋翼无人机(UAV)在轨迹跟踪中的PID控制仿真方法。通过设计三轴方向的PID控制器,调节无人机的姿态与位置,使其能够准确跟踪预设轨迹。本文使用MATLAB/Simulink进行了建模与仿真,验证了PID控制算法在无…...
回归预测|基于卷积神经网络-支持向量机的数据回归预测Matlab程序CNN-SVM 卷积提取特征与原始特征进行融合预测
回归预测|基于卷积神经网络-支持向量机的数据回归预测Matlab程序CNN-SVM 卷积提取特征与原始特征进行融合预测 文章目录 一、基本原理原理流程总结 二、实验结果三、核心代码四、代码获取五、总结 回归预测|基于卷积神经网络-支持向量机的数据回归预测Matlab程序CNN-SVM 卷积提…...
javaScript基础知识汇总
一、基础语法 1、区分大小写:无论是变量、函数名还是操作符,都区分大小写。 2、标识符:就是变量、函数、属性或函数参数的名称。标识符可以由一个或多个字符构成,但需要满足以下条件: 第一个字符必须是一个字母、下…...
《动手学深度学习》笔记2.2——神经网络从基础→进阶 (参数管理-每层的权重/偏置)
目录 0. 前言 正文:参数管理 1. 参数访问 1.1 [目标参数] 1.2 [一次性访问所有参数] 1.3 [从嵌套块收集参数] 2. 参数初始化 2.1 [内置初始化] 2.2 [自定义初始化] 2.3 [参数绑定-共享参数] 3. 小结(第2节) 4. 延后初始化 (原书第…...
双端之Nginx+Php结合PostgreSQL搭建Wordpress
第一台虚拟机:安装 Nginx 更新系统包列表: sudo apt update安装 Nginx及php扩展: sudo apt install nginx php-fpm php-pgsql php-mysqli -y启动 Nginx 服务: sudo systemctl start nginx检查 Nginx 是否正常运行: xdg-open http://localhost注意:终端命令打开网址 …...
Another redis desktop manager使用说明
Another redis desktop manager使用说明 概述界面介绍图示说明连接界面设置界面查看操作日志主界面信息进入redis-cli控制台更多 概述 Another Redis Desktop Manager是一个开源的跨平台 Redis 客户端,提供了简洁易用的图形用户界面(GUI)&am…...
【git】配置 Git 的换行符处理和安全性||安装 Ruby
配置 Git 的换行符处理和安全性: git config --global core.autocrlf input:这个设置确保在提交代码时,Git 会将 CRLF(Windows 的换行符)转换为 LF(Unix 的换行符),但在检出代码时不…...
VMware ESXi 8.0U3b macOS Unlocker OEM BIOS 2.7 Dell HPE 定制版 9 月更新发布
VMware ESXi 8.0U3b macOS Unlocker & OEM BIOS 2.7 Dell HPE 定制版 9 月更新发布 VMware ESXi 8.0U3b macOS Unlocker & OEM BIOS 2.7 标准版和厂商定制版 ESXi 8.0U3 标准版,Dell (戴尔)、HPE (慧与)、Lenovo (联想)、IEIT SYSTEMS (浪潮信息)、Cisco …...
Unity 代码裁剪(Strip Engine Code)
文章目录 0.IL2CPP 打包运行闪退问题1.什么是代码裁剪2.为什么要使用代码裁剪3.代码裁剪设置与级别4.强制保留代码4.1 使用[Preserve]标签4.2 使用Link.xml文件 5.Strip中遇到的问题及解决方法6.注意事项 0.IL2CPP 打包运行闪退问题 Google Play要求从2019年8月1日起apk必须支…...
单目3d重建DUSt3R 笔记
目录 DUSt3R 三维重建 报错RecursionError: maximum recursion depth exceeded in comparison 报错 numpy.core.multiarray failed to import 报错Numpy is not available 解决 升级版mast3r 速度变慢 修改了参数设置脚本: 测试效果 操作技巧 DUSt3R 三维重…...
AI驱动TDSQL-C Serverless 数据库技术实战营-与AI的碰撞
目录 一、简介 二、实验介绍 三、结果展示 四、实操指导 4.1 系统设计 4.2 环境搭建(手把手教程) 4.3 应用构建 4.4 效果展示 4.5 踩坑避雷总结 五、清理资源 5.1 删除TDSQL-C Serverless 5.2 删除 HAI 算力 六、实验总结归纳 一、简介 本…...
C++之String类(上)
片头 嗨!好久不见~ 今天我们来学习C的Sting类,不过,在学习它之前,我们先来对STL库有一个简单的了解。 STL(standard template library--标准模板库),是C标准库的重要组成部分,不仅是…...
kubernets基础-ingress详细介绍
文章目录 什么是IngressIngress详细说明Ingress示例 Ingress控制器Ingress控制器的工作原理Ingress控制器的特点常见的Ingress控制器 Ingress关联Ingress控制器一、Ingress资源对象二、Ingress控制器三、Ingress与Ingress控制器的关联方式四、注意事项 多实例部署一、Ingress多…...
jenkins部署Maven和NodeJS项目
在 Java 项目开发中,项目的编译、测试、打包等是比较繁琐的,属于重复劳动的工作,浪费人力和时间成本。以往开发项目时,程序员往往需要花较多的精力在引用 jar 包搭建项目环境上,跨部门甚至跨人员之间的项目结构都有可能…...
在unity资源中发现无效引用
本文主要解决在不打开unity的情况下搜索出无效引用的资源的方法 1. 概述 一般只要遍历一下目录里所有资源,判空一下就好了但有些情况下,不希望打开unity, 尤其希望是在资源整合时,想更快验证资源的合法性, 这对合并提交及出包验证时,都要较大的需求 2. 简单的验证方法 简单来…...
C#知识|基于反射和接口实现抽象工厂设计模式
哈喽,你好啊,我是雷工! 01 应用场景 在项目的多数据库支持上、业务的多算法封装、以及各种变化的业务中; 02 抽象工厂组成 抽象工厂包括抽象产品(即业务接口,可以通过抽象类或抽象接口设计)…...
【分布式微服务云原生】gRPC vs RPC:深入探索远程过程调用的现代与经典
摘要 在分布式系统的世界里,gRPC和RPC是两个耳熟能详的术语,但它们之间有何区别和联系?本文将深入探讨gRPC和RPC的概念、关键特性、以及它们在现代软件开发中的应用。你将了解到gRPC如何作为RPC的一种实现,提供高性能的跨语言远程…...
听说这是MATLAB基础?
MATLAB(矩阵实验室)是一个强大的高性能计算环境和编程语言,广泛应用于数学计算、算法开发、数据分析、可视化以及模拟等多个领域。以下是MATLAB的一些基础知识,涵盖其功能、语法、基本操作等方面。 1. MATLAB环境 工作区…...
【CSS/HTML】圣杯布局和双飞翼布局实现两侧宽度固定,中间宽度自适应及其他扩展实现
前沿简介 圣杯布局和双飞翼布局是前端重要的布局方式。两者的功能相同,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局。 圣杯布局来源于文章In Search of the Holy Grail,双飞翼布局来源于淘宝UED。 两者的实现方式有差异,但是都…...
数据流和数据流处理技术
一数据流 首先明确数据流概念:数据流是连续不断生成的、快速变化的无界数据序列 数据流类型: 数据流大致可以分为四种类型 1.连续型数据流:不断地产生数据,数据稳定速度输入系统。 2.突发型数据流:在某特定时间或…...
(IDEA)spring项目导入本地jar包方法和项目打包时找不到引入本地jar包的问题解决方案
系列文章目录 文章目录 系列文章目录一、(IDEA)spring项目导入本地jar包方法和项目打包时找不到引入本地jar包的问题解决方案1.资料 一、(IDEA)spring项目导入本地jar包方法和项目打包时找不到引入本地jar包的问题解决方案 1.资料…...
海南网站建设费用/技术短期培训班
某些场景需要读取 css3 transform的属性 例如 transform:translate(10px,10px) rotate(-45deg); 这该怎么读取呢,正则表达式?毫无疑问这很坑爹 试试浏览器getComputedStyle得到的style对象中有没有这些属性,得到的只有matrix(0.866025, 0.5, …...
做的网站怎么上线/网络推广一个月工资多少
有人咨询电热汇问:工业烘箱的安装要求及注意事项是什么?那么今天热汇宝电热汇首先给大家介绍一下工业烘箱的安装要求。一、工业烘箱操作方法(1) 请正确接上三相电源,零线及地线。(2) 打开电源开关,电源指示灯亮同时电压表有指示为…...
图片网站源码asp/基本营销策略有哪些
本文会提到52条SQL语句性能优化策略。 1、对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引。 2、应尽量避免在where子句中对字段进行null值判断,创建表时NULL是默认值,但大多数时候应该使用N…...
投资者互动平台/武汉seo哪家好
转贴自:http://blog.czug.org/panjy/2006/5/ubuntudekouhao-linux-for-human-beings panjy 提交于 2006-05-19 22:31 Linux 罗嗦一下 ubuntu_ 的这个口号。罗嗦一下 ubuntu 的这个口号。 所谓Linux for human beings,说得好听点,可翻译为“…...
网站自动加水印/一件代发48个货源网站
温故: 在上一篇文章《Linux之网络管理——修改IP地址(动态变静态)》给大家讲了如何查看IP地址以及如何将动态IP地址改为静态IP地址。有兴趣的朋友可以看看 知新: 刚刚在做测试的时候使用到了一个大家都很熟悉的命令“Kill”,这个…...
wordpress插件统计/如何创建一个网页
说到对集合去重处理,第一时间想到的肯定是Linq的Distinct扩展方式,对于一般的值类型集合去重,很好处理,直接list.Distinct()即可。但是如果想要对一个引用类型的集合去重(属性值都相同就认为重复)ÿ…...