I'm new to solidity and trying to understand OpenZeppelin's
Context contract. At the time of writing, the documentation says:
While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned).
This contract is only required for intermediate, library-like contracts.
I kind of understand at a high level that
msg.sender can be different from the actual sender for a meta-transaction, but I do not understand how using
_msgData() helps with that. Both functions are simply returning
msg.data and they look no different from directly accessing
_msgSender() in its constructor and modifier
onlyOwner() but I don't understand how that's different from hardcoding
A specific example where calling
_msgSender() is different from
msg.sender would be very helpful!