I have a question about openzeppelin _msgSender helper:

function _msgSender() internal view virtual returns (address payable) {
    return msg.sender;


They say this function is able to give us the real sender, when we use a GSN. But this function contains msg.sender so i do not understand how it works, to detect a GSN usage.

I do not see the value add of this function because the only thing it does is returning msg.sender.

I think i miss something...

Thanks a lot

  • From what I understand, the virtual modifier means that this function is an abstract function, which can be overriden. This function, as is, does not present any benefit over using msg.sender directly. But it other contracts (such as GSN) will override this function.
    – samlaf
    Nov 24, 2021 at 21:09

3 Answers 3


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();

I'm not very familiar with GSN, but that kind of contract structure is quite typical for OpenZeppelin. They have functions which don't seem to do much.

But their structure is built on extendability and hooks: you are meant to inherit their contracts and override the desired functions with your own. So my guess is that GSN code would inherit from that contract and use another implementation instead.


Woow... First time reading about GSN and what they do. This is definitely helpul.

Question is.... How does the using generating the TX pay back the GSN for services provided? Does the GSN get paid in ERC20s?


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.