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

Solidity——什么是低级调用(low-level calls)和操作码的内联汇编

这是 Solidity 高级开发中很重要的两个概念,通常用于:

  • 精细控制合约行为(比如合约间通信、控制 gas、避免 fallback 限制)

  • 编写高性能或底层逻辑的合约(例如代理合约、MEV、Gas 优化等)

我们逐一讲清楚:


✅ 一、什么是 低级调用(Low-level calls)

Solidity 提供了几种**“低级”函数调用方式**,用于替代标准的函数调用。这些函数更原始、更灵活,但使用不当容易出 bug(比如失败不报错、容易被 reentrancy 攻击)。

🔽 常见的低级调用有:

低级函数用途
address.call向地址发交易,可以带 data(常用于代理合约)
address.delegatecall在调用者上下文中执行另一个合约的代码(代理合约核心)
address.staticcall和 call 类似,但只读(不允许写入链上状态)
address.send转 ETH,失败返回 false,不会 revert
address.transfer转 ETH,gas 固定 2300,失败会 revert

✅ 例子 1:call

(bool success, bytes memory data) = address(target).call(abi.encodeWithSignature("doSomething(uint256)", 123)
);
  • success 是是否成功的标志

  • data 是返回的字节数据(需要用 abi.decode 解码)


✅ 例子 2:delegatecall

(bool success, ) = address(lib).delegatecall(abi.encodeWithSignature("increment()")
);
  • 执行的是 lib 合约的函数

  • 但使用的是 当前合约的 storage

  • 常用于 可升级合约(proxy pattern)


⚠️ 低级调用风险:

  • 不会自动 revert,必须检查 success 否则可能吞错

  • 容易遭遇重入攻击(尤其是 call 后调用外部合约)

  • 可读性差,调试难


✅ 二、什么是 内联汇编(Inline Assembly)

Solidity 支持使用 Yul 或旧版本的汇编语言 直接写 EVM 操作码。这可以让你:

  • 完全掌控执行逻辑

  • 做极致 gas 优化

  • 使用 Solidity 无法访问的底层功能


🔽 语法:

assembly {let x := add(1, 2)sstore(0x0, x)
}

这是 Yul 风格汇编(推荐)。这里:

  • add 是 EVM 操作码(加法)

  • sstore 把值写入 storage


✅ 示例:获取调用者地址

function getCaller() public view returns (address caller) {assembly {caller := caller()}
}

等价于 msg.sender,但这是纯操作码形式。


📌 用内联汇编的原因:

场景为什么要用汇编?
Gas 极致优化比 Solidity 更轻量的操作方式
操作内存 / 存储地址控制Solidity 语法无法表达的东西
与其它语言/合约兼容(例如代理)手动构造函数选择器 / calldata

✅ 总结对比:

名称是什么使用场景
低级调用call、delegatecall、staticcall 等原始调用方式跨合约通信、代理合约
内联汇编写原始的 EVM 操作码性能极致、底层访问、操作存储或 calldata

⚠️ 使用建议:

  • 没有特殊需求,避免用低级调用和汇编(容易出错)

  • 如果做代理合约、升级逻辑、MEV、DeFi 细节处理,这些是必备工具

  • 内联汇编在 Solidity 0.8+ 中推荐用 Yul 风格(可读性更强)


如果你想,我可以给你写一个代理合约 + delegatecall 示例,或者手动拼接 calldata 的内联汇编 demo。需要吗?

http://www.dtcms.com/a/267991.html

相关文章:

  • 一次内存“卡顿”全流程实战分析:从制造问题到优化解决
  • Apache Spark 4.0:将大数据分析提升到新的水平
  • 小架构step系列06:编译配置
  • 在C#中,可以不实例化一个类而直接调用其静态字段
  • 2025年03月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • python-转义字符
  • 李宏毅2025《机器学习》第四讲-Transformer架构的演进
  • 力扣971. 寻找图中是否存在路径【simple 拓扑排序/图 Java】
  • 【双向循环带头链表】
  • Java中的抽象类和接口
  • CICD[构建镜像]:构建django使用的docker镜像
  • 【9】用户接入与认证配置
  • 车载智能座舱用户画像系统研究二:子系统构建
  • Linux国产与国外进度对垒
  • GANs环境应用及启发思考
  • java学习——guava并发编程练习
  • 跨平台游戏引擎 Axmol-2.7.0 发布
  • @Data、@AllArgsConstructor、@NoArgsConstructor不生效。lombok不起作用怎么解决?
  • 设置LInux环境变量的方法和区别_Ubuntu/Centos
  • 网页怎么不使用工具截图和长图
  • 《Spring AI实战:Java智能开发速成指南》
  • D435i + ROS2
  • 利用selenium获取网页数据,脚本加载慢问题的解决办法
  • CentOS环境搭建-快速升级G++版本
  • 【CSS样式】有趣的滑块开关
  • 深入理解 classnames:React 动态类名管理的最佳实践
  • 20250706-6-Docker 快速入门(上)-镜像是什么?_笔记
  • TNNLS期刊接受后,最终版提交说明
  • QT - QCustomPlot
  • Next.js面试常问内容详解