GSN Lets the gas station pay the fee instead of your user who is sending the transaction. Essentially what happens is that you ask the GSN to send the transaction to the network through a signed message.
If you use a GSNRecipient
interface, _msgSender function will get the sender address from the signed payload since msg.sender will always be the GSN
Ref: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/GSN/GSNRecipient.sol#L90
// Overrides for Context's functions: when called from RelayHub, sender and
// data require some pre-processing: the actual sender is stored at the end
// of the call data, which in turns means it needs to be removed from it
// when handling said data.
/**
* @dev Replacement for msg.sender. Returns the actual sender of a transaction: msg.sender for regular transactions,
* and the end-user for GSN relayed calls (where msg.sender is actually `RelayHub`).
*
* IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.sender`, and use {_msgSender} instead.
*/
function _msgSender() internal view virtual override returns (address payable) {
if (msg.sender != getHubAddr()) {
return msg.sender;
} else {
return _getRelayedCallSender();
}
}
virtual
modifier means that this function is an abstract function, which can be overriden. This function, as is, does not present any benefit over usingmsg.sender
directly. But it other contracts (such as GSN) will override this function.