I’ve seen many contracts that instead of using msg.sender directly, they use a function that returns the msg.sender, why is this?
_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).
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)
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()
-
-
For a normal transaction , like deploying openzeppelins
ERC20
,msgSender()
will simply give backmsg.sender
-
For meta transactions
msgSender()
acts differently . AddressA
submits offchain signed data to arelayer.
Therelayer
then submits the transaction on-chain to arelayHub
contract which in turn calls arecipient
contract .msgSender()
in this type of meta-transaction givesaddress A
notmsg.sender