Why use _msgSender() rather than msg.sender?

I’ve seen many contracts that instead of using msg.sender directly, they use a function that returns the msg.sender, why is this?

2 Likes

Hi @franco_villa_santana,

_msgSender() is a replacement for msg.sender. For regular transactions it returns msg.sender and for meta transactions it can be used to return the end user (rather than the relayer).

6 Likes

Is _msgSender() same as tx.origin then?

No, it isn't

The _msgSender() is a virtual function that can be overridden, so for a basic smart contract, it doesn't do much, it just returns msg.sender

But for a GSN-like contract, _msgSender is overridden and _msgSender would return the sender via payload(maybe msg.data) and not the actual caller

You could take a look at this for reference openzeppelin-contracts/GSNRecipient.sol at v3.4.0 · OpenZeppelin/openzeppelin-contracts (github.com)

1 Like

If address A sends a transaction to Contract A, Contract A calls Contract B.

For Contract B, can I think that the msg.sender will return the address of Contract A and _msgSender() will return the address A.

Thanks!

That's not the right explaination .

Simplest explanation for msgSender() -

  1. For a normal transaction , like deploying openzeppelins ERC20 , msgSender() will simply give back msg.sender

  2. For meta transactions msgSender() acts differently . Address A submits offchain signed data to a relayer. The relayer then submits the transaction on-chain to a relayHub contract which in turn calls a recipient contract . msgSender() in this type of meta-transaction gives address A not msg.sender