深入理解 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 算力 六、实验总结归纳 一、简介 本…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...