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

Solidity——pure 不消耗gas的情况、call和sendTransaction区别

/ pure: 纯纯牛马 function addPure(uint256 _number) external pure returns(uint256 new_number){ new_number = _number + 1; }不会消耗gas对吧。传的不是状态变量

你的理解基本对了,但我们来更严谨、深入地回答这个问题。


✅ 你这段 pure 函数代码:

function addPure(uint256 _number) external pure returns(uint256 new_number) {new_number = _number + 1;
}

这是一个非常典型的 pure 函数:

  • ✅ 不读取任何链上状态变量

  • ✅ 不写入链上状态变量

  • ✅ 只是计算输入值 _number + 1,然后返回


❓会不会消耗 gas?

场景是否消耗 gas原因解释
用 call 调用(比如 Remix 蓝色按钮、本地调用)❌ 不消耗函数在本地执行,不上链,不发交易
用 sendTransaction 发交易调用✅ 会消耗虽然函数是 pure,但只要发了交易、上了链,就会消耗 gas(因为 EVM 要执行它)

✅ 举例说明:

1. 使用 Remix 调用(或 web3/ethers call):
const result = await contract.addPure(123); // ✅ 不消耗 gas

这是 本地仿真运行,不发交易,完全不花钱。适合做链下计算。


2. 使用 sendTransaction 方式调用:
await contract.addPure(123, { from: user });

就算函数是 pure,因为你发了交易,EVM 还是要执行它、打包进区块,所以:

  • ✅ 会消耗 gas(比如 21,000 ~ 30,000)

  • ❌ 不会改链上状态

  • ⚠️ 不推荐这么用,没意义还浪费 gas


🧠 小结:

函数类型pure
是否能读状态❌ 不行
是否能改状态❌ 不行
是否消耗 gas?✅ 发交易才消耗;❌ 用 call 就不消耗

🚀 一句话总结:
只要你调用 pure/view 函数时用的是 call,不发交易,就不花 gas。


需要我帮你写一个对比:pure、view、write 三种函数并观察 Remix 上 gas 消耗差异的完整演示代码吗?

二、call和sendTransaction区别

你问得非常好!这是很多 Solidity 初学者在实际调用合约时都会混淆的核心概念。我们现在来彻底讲清楚什么是 sendTransaction 方式,以及为什么你写的那种方式就是。


✅ 先定义:什么是 sendTransaction?

在以太坊中:

sendTransaction 是指:向区块链发起一笔真实交易(transaction),从一个地址调用一个合约函数,消耗 gas,可能改变链上状态。


🔍 举个类比说明:

操作方式类似于做什么会不会上链会不会花 gas使用函数类型
call查看数据、模拟执行❌ 否❌ 否view / pure
sendTransaction正式签名 + 发交易 + 广播✅ 是✅ 是(一定会)non-view/任意

✅ 回到你的例子:

await contract.addPure(123, { from: user });

这行代码,在 web3.jsethers.js 中,如果你用 await 调用了一个合约的函数,并且它不是 .call().staticCall(),那么默认行为就是发起一笔真实交易,也就是 sendTransaction


🧨 它其实等价于这样:

await contract.methods.addPure(123).send({ from: user });
  • 这就会触发一笔链上交易

  • 即使 addPure()pure 函数

  • 你也会花 gas(比如 21,000)

  • 但结果你无法直接拿到返回值,因为链上交易不返回值


⚠️ 非常重要的对比:

用法是否发交易(sendTransaction)能不能返回结果是否消耗 gas
contract.methods.foo().call()❌ 否(只读模拟)✅ 可以获取结果❌ 不花钱
contract.methods.foo().send()✅ 是(发交易)❌ 无法直接获取✅ 要花 gas

✅ 正确方式:调用 pureview 函数推荐用 .call()

const result = await contract.methods.addPure(123).call(); // ✅ 推荐方式
console.log(result); // 124
  • .call() 是本地调用,不会发交易

  • 不会花钱

  • 可以立刻获取返回值


✅ 总结一句话:

只要你用的是 .send() 或不带 .call() 的 await 函数调用,并且指定了 { from: ... },那就是发了交易(sendTransaction),会 上链、花 gas、不直接返回结果


如果你想,我可以再写一段完整的 ethers.js 示例,对比 .call.sendTransaction 两种方式的执行行为。需要吗?

http://www.lryc.cn/news/581766.html

相关文章:

  • 【算法刷题记录(简单题)003】统计大写字母个数(java代码实现)
  • Node.js特训专栏-实战进阶:13. ORM/ODM工具选型与使用
  • AI做美观PPT:3步流程+工具测评+避坑指南
  • 【论文笔记】【强化微调】Pixel Reasoner:早期 tool call 的调用
  • CppCon 2018 学习:Undefined Behavior is Not an Error
  • 【系统分析师】2022年真题:论文及解题思路
  • (二) TDOA(到达时间差)、AoA(到达角度)、RSSI(接收信号强度)、TOF(飞行时间) 四种定位技术的原理详解及对比
  • 手动使用 Docker 启动 MinIO 分布式集群(推荐生产环境)
  • 从前端转go开发的学习路线
  • 2025 BSidesMumbaiCTF re 部分wp
  • NLP文本预处理
  • Spring AI(12)——调用多模态模型识别和生成图像
  • MyBatis实战指南(九)MyBatis+JSP+MySQL 前端页面实现数据库的增加与删除显示数据
  • 分布式会话的演进和最佳事件,含springBoot 实现(Java版本)
  • 【网络安全】不要在 XSS 中使用 alert(1)
  • 电池预测 | 第33讲 Matlab基于CNN-LSTM-Attention的锂电池剩余寿命预测,附锂电池最新文章汇集
  • 一个简单的脚本,让pdf开启夜间模式
  • 【STM32】通用定时器PWM
  • 李宏毅NLP-8-语音模型
  • 20250706-11-Docker快速入门(下)-构建Nginx镜像和Tomcat镜像_笔记
  • Kotlin lazy 委托的底层实现原理
  • styled-components:现代React样式解决方案
  • 构建下一代智能应用:RAG系统开发深度指南
  • 基于STM32单片机的心率血氧监测系统设计(STM32代码编写+手机APP设计+PCB设计+Proteus仿真)
  • C# 接口(什么是接口)
  • 【机器学习笔记Ⅰ】1 机器学习
  • .golangci.yml文件配置
  • C语言学习(第一天)
  • 求医十年,病因不明,ChatGPT:你看起来有基因突变
  • Gin 框架中如何实现 JWT 鉴权中间件