By using ether.js
you could call contract.connect(<signer>)
to change the context, in other words msg.sender
address.
This signer should be a wallet/account, it could not be another contract. However when inside your contract this contract calls another contract msg.sender
would be an address of the contract caller – not an address which was defined during the initial call, e.g. contract.connect(<signer>)
.
It might be important during ERC721
token approve call: we could approve one address, but eventually authorized ERC721
token function would be called by deployed contract which would end up with revered tx as this address has not been approved.
In short: msg.sender
it is an address of contract caller - it would be a user's address who calls the contract or the contract's address who calls another contract despite on the origin caller is the user.