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

请教:Solidity智能合约中msg.sender与from地址的区别是什么?二者是否为交易发起方?及ERC20合约创建规范下二者的差异疑问

Understanding msg.sender vs. from Address in Solidity & ERC20

Hey there! Let’s clear up these two common confusion points—they’re tricky at first, but once you wrap your head around the context, it all clicks.

1. General Solidity: msg.sender vs. Transaction from Address

First, let’s break down the two concepts at a fundamental level:

  • Transaction from address: This is the address of the External Owned Account (EOA) that initiated the entire transaction on the Ethereum network. Think of this as the "root" initiator—like your MetaMask wallet address when you click "Send" to interact with a contract. This value is fixed for the entire transaction and is verified by the network, not the contract itself.
  • msg.sender: This is a Solidity global variable that refers to the immediate caller of the current function. Crucially, this can be either an EOA or another smart contract.

Here’s a concrete example to illustrate the difference:
Suppose you (EOA 0x123) call a function trigger() in Contract A, which in turn calls a function execute() in Contract B.

  • The transaction’s from address is always 0x123 (you, the original initiator).
  • In Contract A’s trigger() function, msg.sender is 0x123 (since you directly called this function).
  • In Contract B’s execute() function, msg.sender is Contract A’s address (not 0x123), because Contract A was the immediate caller of this function.

So to answer your question: The transaction from is always the original EOA that started the transaction, while msg.sender is the direct caller of the current function. They only match when you directly call a contract function from an EOA—when contracts call each other, they diverge.

2. ERC20 Smart Contracts: msg.sender vs. from Parameter

In ERC20, the from you’re referring to is almost always the parameter in the transferFrom(address from, address to, uint256 amount) standard function. Let’s break down how this interacts with msg.sender:

  • transfer(address to, uint256 amount): This function doesn’t have a from parameter because it assumes the sender of the tokens is msg.sender. When you call transfer(), you’re telling the contract: "Take amount tokens from my address (msg.sender) and send them to to."
  • transferFrom(address from, address to, uint256 amount): This is the "approved transfer" function. Here, the from parameter is the address that owns the tokens you want to send, and msg.sender is the address that has been authorized by from to spend their tokens.

Here’s a simplified snippet of how transferFrom might look in an ERC20 contract to make this tangible:

function transferFrom(address from, address to, uint256 amount) public returns (bool) {
    // Check if msg.sender has enough allowance from 'from'
    require(allowance[from][msg.sender] >= amount, "Insufficient allowance");
    
    // Deduct the approved allowance
    allowance[from][msg.sender] -= amount;
    // Execute the token transfer from 'from' to 'to'
    _transfer(from, to, amount);
    return true;
}

Example scenario:
You (EOA 0x123) approve 0x456 to spend up to 100 of your ERC20 tokens. Then 0x456 calls transferFrom(0x123, 0x789, 50).

  • msg.sender is 0x456 (the address calling the function).
  • from is 0x123 (the address that owns the tokens being sent).
  • The contract checks if 0x456 has enough approved allowance from 0x123, then transfers 50 tokens from 0x123 to 0x789.

In short, in ERC20:

  • msg.sender is the entity (EOA or contract) making the function call.
  • The from parameter (in transferFrom) is the token owner whose tokens are being moved—only possible if msg.sender has been granted permission to spend those tokens.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 21:42:40