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

合约构造函数调用外部合约函数时msg.sender的取值是多少

智能合约构造函数跨合约调用的msg.sender值说明

首先给出明确结论:被调用函数获取到的msg.sender是正处于部署阶段的当前新合约的预计算地址,而非发起部署交易的外部账户(EOA)地址。

原理说明

  • EVM在执行合约构造函数之前,就已经通过部署者地址、部署交易的nonce(如果使用CREATE2部署则为salt值、合约字节码哈希等参数)提前计算出了新合约的最终链上地址,这个地址在构造函数执行全程都是固定不变的,不会受部署进度影响。
  • 构造函数的执行上下文从一开始就绑定了这个预计算的新合约地址,因此只要是构造函数内部触发的外部合约调用,消息的发起方都会被标记为这个预计算地址,哪怕此时新合约的代码还没有完全写入链上。

验证示例

可以通过以下极简Solidity代码复现验证:

// 被调用的测试合约
contract TargetContract {
    address public recordedCaller;

    function saveCaller() external {
        recordedCaller = msg.sender;
    }
}

// 部署时会调用上述测试合约的业务合约
contract NewContract {
    address public myAddress;

    constructor(address _targetAddr) {
        // 构造函数内先获取自身地址
        myAddress = address(this);
        // 调用外部合约方法
        TargetContract(_targetAddr).saveCaller();
    }
}

部署完成后对比两个合约的存储值就会发现:NewContract.myAddress 和 TargetContract.recordedCaller 完全相等,就是新部署合约的链上地址。

注意不要和部署交易的发起方地址混淆:只有部署交易直接执行的顶层上下文中msg.sender是发起部署的EOA地址,一旦进入新合约的构造函数执行环境,后续所有调用的发起方都会默认使用新合约的预计算地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 22:18:04