当前位置: 首页 > news >正文

Solidity智能合约中的异常处理(error、require 和 assert)

Solidity 中的三种抛出异常方法:errorrequireassert


在 Solidity 开发中,异常处理是确保智能合约安全性和正确性的关键步骤。Solidity 提供了三种主要方法来抛出异常:errorrequireassert。本文将详细介绍这三种方法的用途、实现方式及其各自的特点,并对它们的 Gas 消耗进行比较。


目录

  1. Solidity 中的异常处理
    1.1 什么是异常?
    1.2 异常处理的必要性
    1.3 Solidity 异常的常见场景

  2. error:自定义错误
    2.1 error 的定义
    2.2 error 的使用场景
    2.3 error 的语法
    2.4 error 的Gas消耗

  3. require:前置条件检查
    3.1 require 的作用
    3.2 require 的语法
    3.3 require 的常见使用场景
    3.4 require 的 Gas 消耗

  4. assert:不变量检查
    4.1 assert 的作用
    4.2 assert 的语法
    4.3 assert 的使用场景
    4.4 assert 的 Gas 消耗

  5. 三者的对比与最佳实践
    5.1 功能对比
    5.2 安全性对比
    5.3 Gas 消耗对比

  6. 总结

在这里插入图片描述

1. Solidity 中的异常处理

1.1 什么是异常?

异常是指在程序运行过程中发生的不正常或意外的情况。在 Solidity 中,异常通常指程序遇到错误条件时的中断执行。

1.2 异常处理的必要性

在智能合约中,异常处理的目标是确保交易不会在有错误的情况下继续执行,以防止状态被意外更改或资金被错误转移。

1.3 Solidity 异常的常见场景

  • 用户输入不合法(如溢出、负值等)
  • 外部合约调用失败
  • 合约逻辑中的不变量遭到破坏
  • 资金不足或无法执行转账

2. error:自定义错误

2.1 error 的定义

error 是 Solidity 0.8.4 版本引入的新特性,允许开发者定义自定义错误。自定义错误为错误报告提供了更多的灵活性,并且能够节省 Gas。

2.2 error 的使用场景

自定义错误主要用于需要抛出特定的异常并提供更详细的错误信息的场景。它相比传统的异常处理方式,可以节省 Gas,尤其是在复杂合约中。

2.3 error 的语法

// 定义错误
error InsufficientBalance(uint requested, uint available);contract Token {function withdraw(uint amount) public {if (amount > address(this).balance)revert InsufficientBalance({requested: amount,available: address(this).balance});// 继续执行其他逻辑}
}

2.4 error 的Gas消耗

使用 error 定义自定义错误时,相比 requireassert,通常会节省更多的 Gas,尤其是当错误需要包含复杂数据时。由于错误消息不作为字符串存储,它的处理更加高效。


3. require:前置条件检查

3.1 require 的作用

require 用于在合约执行之前检查某些条件是否成立,通常用于验证输入参数或外部合约调用结果。

3.2 require 的语法

function transfer(address recipient, uint amount) public {require(amount <= balance, "Insufficient balance");// 执行转账
}

3.3 require 的常见使用场景

  • 检查调用方是否具有足够的权限
  • 验证输入数据的合法性
  • 验证外部合约的返回值

3.4 require 的 Gas 消耗

require 语句会消耗一定的 Gas,但由于 require 在条件不满足时立即中断执行,未使用的 Gas 会被退还。因此,require 适合用于条件检查时。


4. assert:不变量检查

4.1 assert 的作用

assert 用于检查代码逻辑中的不变量,即程序在任何时候都应该满足的条件。如果 assert 失败,意味着代码中存在致命的错误。

4.2 assert 的语法

uint x = 0;function increment() public {x += 1;assert(x > 0); // 确保 x 永远大于 0
}

4.3 assert 的使用场景

  • 用于捕捉代码中的严重错误,特别是不应该发生的逻辑错误。
  • 检查合约中的状态是否在预期范围内。

4.4 assert 的 Gas 消耗

assert 失败时会消耗所有剩余的 Gas,因为它通常用来捕捉不可预见的严重错误。因此,应慎用 assert,只在关键性逻辑的检查中使用。


5. 三者的对比与最佳实践

5.1 功能对比

  • error 提供了更灵活的错误报告机制,适合复杂错误处理。
  • require 适用于输入验证和外部合约结果检查。
  • assert 主要用于捕获不可预见的内部错误或逻辑漏洞。

5.2 安全性对比

  • errorrequire 通常用于用户或合约交互时的错误检查。
  • assert 应用于确保内部逻辑的不变量,更多用于调试目的。

5.3 Gas 消耗对比

  • error:节省 Gas,尤其是复杂的错误处理。
  • require:较为高效,未使用的 Gas 可退还。
  • assert:在失败时消耗所有 Gas,应用场景更局限。

6. 总结

Solidity 提供了 errorrequireassert 三种异常处理方式,每种方式都有其特定的应用场景。开发者应根据合约的实际需求和安全性要求,选择适合的异常处理机制。此外,Gas 消耗的比较也提示我们在大多数情况下,应优先使用 require 进行输入检查,使用 error 进行复杂错误处理,而 assert 应仅用于关键性的不变量检查。


相关文章:

Solidity智能合约中的异常处理(error、require 和 assert)

Solidity 中的三种抛出异常方法&#xff1a;error、require 和 assert 在 Solidity 开发中&#xff0c;异常处理是确保智能合约安全性和正确性的关键步骤。Solidity 提供了三种主要方法来抛出异常&#xff1a;error、require 和 assert。本文将详细介绍这三种方法的用途、实现方…...

True NAS禁用ipv6

在 TrueNAS Scale 中&#xff0c;禁用 IPv6 的方法如下&#xff1a;12 进入 System->Advanced->Sysctl&#xff0c;设置一个 sysctl 可调整变量 net.ipv6.conf.all.disable_ipv6&#xff0c;值为 1&#xff0c;以完全禁用 IPv6。\...

笔记整理—linux进程部分(2)使用fork创建进程

为什么要创建进程&#xff0c;首先每个程序的运行都需要一个进程&#xff1b;多进程实现宏观上的并行。 fork的原理&#xff0c;是进程的分裂生长模式。如果操作系统需要一个新的进程&#xff0c;那么就会以cp的方法得到一个新的进程&#xff0c;此时老的进程是父进程&#xff…...

在Python中实现多目标优化问题(6)

在Python中实现多目标优化问题 在Python中实现多目标优化&#xff0c;除了传统的进化算法&#xff08;如NSGA-II、MOEA/D&#xff09;和一些基于机器学习的方法外&#xff0c;还有一些新的方法和技术。这些新方法通常结合了最新的研究成果&#xff0c;提供了更高效的解决方案。…...

Java EE中的编码问题及解决方案

Java EE中的编码问题及解决方案 在Java EE开发中&#xff0c;处理字符编码是确保数据正确传输和显示的重要环节。不同的编码不一致会导致乱码&#xff0c;影响用户体验。本文将总结在Java EE中可能遇到的编码问题及其解决方案。 1. 输入数据编码问题 在表单提交时&#xff0c…...

9月27日,每日信息差

第一、中国科学家团队在干细胞治疗领域取得重要突破&#xff0c;通过化学重编程技术成功制备出胰岛细胞&#xff0c;并用于移植治疗一名 1 型糖尿病患者&#xff0c;实现了临床功能性治愈。相关研究成果已发表在国际权威期刊《细胞》上。 第二、交通运输部公路局局长周荣峰在国…...

什么是 Angular 开发中的 Dumb components

Dumb components&#xff0c;在 Angular 开发中也被称为 Presentational components&#xff0c;它们的主要职责是通过展示数据和触发事件&#xff0c;把业务逻辑和 UI 表现分离开来。Dumb components 只通过 Input() 接收数据&#xff0c;Output() 向外发送事件&#xff0c;不…...

Docker 进入容器运行命令的详细指南

Docker 进入容器运行命令的详细指南 Docker 是一个开源的容器化平台&#xff0c;广泛应用于开发和生产环境中。它允许开发者打包应用程序及其依赖项到容器中&#xff0c;并能够在不同的平台上快速部署和运行。容器通常是独立且隔离的&#xff0c;但在开发、调试或维护过程中&a…...

如何禁止非真实用户的ip访问网站服务器

为了禁止非真实用户的IP访问网站服务器&#xff0c;可以采用多种技术手段和策略。以下是一些常用的方法&#xff1a; 1. 使用IP黑名单和白名单 黑名单&#xff1a;定期更新和维护一个IP黑名单&#xff0c;阻止已知的恶意IP地址或数据中心IP访问网站。白名单&#xff1a;对于特…...

探索SpringBoot:学科竞赛管理项目开发

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…...

ultralytics yolo v8 示例:加载官方模型进行推理

Ultralytics YOLO 是计算机视觉和 ML 领域专业人士的高效工具。 安装 ultralytics 库&#xff1a; pip install ultralytics 实现代码如下&#xff1a; import cv2 from ultralytics import YOLO# 加载预训练的 YOLOv8n 模型 ckpt_dir "./ckpt/" # 模型缓存地址…...

【中间件学习】Nginx快速入门(为了配置一个项目)

-----------------------------本文章借鉴遇见狂神说--------------------------- 一、一个产品出现瓶颈&#xff1f;&#xff1f; 在一个产品刚刚上线的时候&#xff0c;并发量小&#xff0c;用户使用的少&#xff0c;所以在低并发的情况下&#xff0c;一个jar包启动应该就够…...

鸿蒙harmonyos next flutter通信之MethodChannel获取设备信息

本文将通过MethodChannel获取设备信息&#xff0c;以此来演练MethodChannel用法。 建立channel flutter代码&#xff1a; MethodChannel methodChannel MethodChannel("com.xmg.test"); ohos代码&#xff1a; private channel: MethodChannel | null nullthis.c…...

【笔记】原子结构的近代理论

近代原子结构理论的建立是从氢原子光谱得到启示的。 一、氢原子光谱与波尔理论 1.氢原子光谱 在装有两个电极的真空玻璃管内通入极少量高纯氢气&#xff0c;通高压电使之放电&#xff0c;管中发出的光束通过分光棱镜&#xff0c;得到分立的谱线&#xff0c;称为线状光谱。 发…...

【python】循环中断:break 和 continue

目录&#xff1a; while 循环的基础语法while 循环的基础案例while 循环的嵌套应用while 循环的嵌套案例for 循环的基础语法for 循环的嵌套应用循环中断&#xff1a;break 和 continue综合案例 学习目标&#xff1a; 掌握使用 continue 和 break 关键字控制循环 思考&#…...

WIFI密码默认显示

文章目录 需求分析遇到问题问题原因解决方案 需求 在进入设置&#xff0c;点击某一个wifi,连接wifi 界面&#xff0c;显示密码默认选中状态&#xff0c;效果如下 分析 在 WiFi密码被输入法挡住 中我们已经分析了整个流程&#xff0c;布局文件和控制中心。 结局系统设置WIFI连…...

Emiya 家今天的饭C++

题目&#xff1a; 样例解释&#xff1a; 【样例 1 解释】 由于在这个样例中&#xff0c;对于每组 i,j&#xff0c;Emiya 都最多只会做一道菜&#xff0c;因此我们直接通过给出烹饪方法、主要食材的编号来描述一道菜。 符合要求的方案包括&#xff1a; 做一道用烹饪方法 1、主要…...

Mybatis缓存机制(图文并茂!)

目录 一级缓存 需求我们在一个测试中通过ID两次查询Monster表中的信息。 二级缓存 案例分许(和上述一样的需求) EhCache第三方缓存 在了解缓存机制之前&#xff0c;我们要先了解什么是缓存&#xff1a; ‌缓存是一种高速存储器&#xff0c;用于暂时存储访问频繁的数据&…...

Git 工作区、暂存区和版本库

Git 工作区、暂存区和版本库 Git 是一个强大的版本控制系统&#xff0c;它帮助开发者管理代码历史&#xff0c;协作开发&#xff0c;以及跟踪和合并更改。为了更好地理解 Git 的工作流程&#xff0c;我们需要了解 Git 中的三个核心概念&#xff1a;工作区&#xff08;Workspac…...

SSH 远程连接到 Linux 服务器上的 SQLite

通过 SSH 远程连接到 Linux 服务器上的 SQLite 数据库文件的流程&#xff0c;可以分为以下几个步骤&#xff1a; 通过 SSH 连接到远程 Linux 服务器。在远程服务器上执行 SQLite 命令行工具&#xff0c;操作数据库文件。在本地使用工具&#xff0c;通过 SSH 隧道间接访问远程的…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...