Who is msg.sender in a nested call chain?

by Paul Berg   Last Updated July 19, 2019 21:28 PM

I read about who is msg.sender when calling a contract from a contract, but who is msg.sender when calling a contract from a contract that calls another contract and so on and so forth?



Answers 1


Let's take this snippet, which you can deploy for yourself on Remix:

pragma solidity 0.5.10;

contract A {

    event LogMsgSender(address who);

    function callMe() public {
        emit LogMsgSender(msg.sender);
    }
}

contract B {

    function callMe(address a) public {
        A(a).callMe();
    }
}

contract C {

    function callMe(address a, address b) public {
        B(b).callMe(a);
    }
}

contract D {

    function callMe(address a, address b, address c) public {
        C(c).callMe(a, b);
    }
}

Calling each method, we get the following results:

  • A.callMe() logs the actual transaction sender.
  • B.callMe(a) logs B's address.
  • C.callMe(a, b) also logs B's address.
  • D.callMe(a, b, c) also log's B's address.

Thus, no matter how deep the nested call chain, msg.sender is always the address of the last but one contract.

Paul Berg
Paul Berg
July 19, 2019 19:58 PM

Related Questions




Regarding Issue in retrieval data from mapping

Updated July 12, 2017 11:28 AM

Would `throw` prevent this recursive attack?

Updated July 17, 2017 21:28 PM