You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么调用零地址时,assembly中的delegatecall()返回1而非0?

问题根因

这是不同EVM执行客户端的实现差异,不属于以太坊核心规则的变更,你之前在Ganache观察到的行为属于Ganache的非标准自定义逻辑:

  • 原生EVM规则下,delegatecall的返回状态码为success(即1)的唯一前提是调用没有被显式终止/抛出异常。调用没有部署代码的账户(包括零地址)默认是执行成功的,仅返回空数据,状态码会返回1,不会进入revert分支。零地址本身没有任何代码,触发调用相当于执行了空指令流,EVM不会主动抛出异常,这是符合黄皮书定义的标准行为。
  • 旧版本Ganache为了降低开发者的调试成本,额外增加了零地址调用校验逻辑:当检测到call/delegatecall/staticcall的目标为零地址时,会主动将调用状态置为失败返回0,这个逻辑是Ganache自行实现的,和主网行为不一致。你现在使用的Hardhat Network严格对齐主网EVM规则,所以表现为返回1进入成功分支。

修复建议

你可以选择以下任意一种方式修复该问题:

  • 在Solidity层提前做合法性校验,避免进入assembly逻辑:
// 校验目标地址不为零
require(destination != address(0), "Invalid implementation address");
// 可选:额外校验目标地址确实部署了合约代码
require(destination.code.length > 0, "Implementation has no code");
  • 直接在assembly块内增加校验逻辑,不需要额外提升到Solidity层:
// 在delegatecall执行前插入以下逻辑
if iszero(destination) {
    mstore(0x00, 0xa91947cd00000000000000000000000000000000000000000000000000000000) // 错误选择器,可自定义
    revert(0x00, 0x04)
}

内容的提问来源于stack exchange,提问作者Whytecrowe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:45:02