58

When I call a function in my contract which calls another function in another contract. In the second called contract function who is msg.sender? the contract calling the second contract or my account?

5 Answers 5

42

Just to add to Jesse's answer. tx.origin is supposed to be the account that signed a transaction. This sounds useful in principle, but in practice, it has been shown that the value can be spoofed.

That means you can only use tx.origin when you're interested in the user identity but security isn't a concern, so ... err .. never. It's possible such a use-case exists, but I've yet to see it.

You can successfully design things with the origin in mind, using msg.sender as the reliable input. Just pass it into functions in contracts further down the chain.

function callOther() public returns(bool success) {
  return other.doSomething(msg.sender);
}

and, in "Other",

function doSomething(address origin) public returns(bool success) {
  // origin is the original initiator
  // msg.sender is the contract that called this. 
}

Hope it helps.

7
  • 2
    Spoofed? At the protocol level, or at the application level (e.g. an oracle)?
    – Jesbus
    Commented Oct 21, 2017 at 21:00
  • 3
    Better if I refer to sources: github.com/ethereum/solidity/issues/683 Commented Oct 21, 2017 at 21:11
  • 3
    Spoofed seems to be incorrect here. Yes, there are criticism to its use, but spoofable is nowhere in the issue. Commented Jul 10, 2018 at 20:04
  • 2
    "Spoof" is the wrong word for a contract impersonating someone else to a contract that relies on tx.origin? Commented Jul 10, 2018 at 23:33
  • 2
    For completeness, you can even call a function within the same contract externally from another function with this.myFunc(), which allows you to change the message sender from account that signed the transaction to the contract itself. It's useful in certain situations for added security, where the initially called function has to run specific checks, which would then call another function. The function called by contract would, for example, restrict only owner of the contract or contract itself to call it. That is, it's not limited to behaving as a child or private function. Commented Nov 12, 2018 at 19:04
52

msg.sender will be the contract calling the contract.

tx.origin will be the account that initiated the chain of contract calls.

3
  • 9
    To add to this: Inside a contract's constructor, msg.sender is the address that is deploying the contract.
    – Jesbus
    Commented Nov 14, 2018 at 15:14
  • Is this answer still true in solidity versions 0.8.13 and up? I'm seeing that msg.sender is always the original transaction signer all throughout the chain of contract calls...
    – Jim
    Commented Jan 5, 2023 at 18:00
  • 1
    Still true. It's the inner-most caller. Commented Jan 6, 2023 at 16:10
11

Caller -> ContractA -> ContractB

Contract A is msg.sender in ContractB's case

1
  • Is this answer still true in solidity versions 0.8.13 and up? I'm seeing that msg.sender is always the original transaction signer all throughout the chain of contract calls...
    – Jim
    Commented Jan 5, 2023 at 18:00
3

When you call a contract internally, the msg.sender is the original sender. In the contract below, the event which is emitted by the function emitEvent in the ChildContract emits the caller of the internal call and not the address of the contract.

pragma solidity ^0.4.24;

contract ChildContract {
    event CalledBy(address callee);
    function emitEvent() internal {
        emit CalledBy(msg.sender);
    }
}

contract Caller is ChildContract {
    function internalCall() {
        emitEvent();
    }
}
3

@Rinke Hendriksen:

This is so because when you deploy your code, there will never be a call between two contracts anywhere.

When you deploy the Caller contract on the Ethereum network it will also include the ChildContract code (as ChildContract is base contract for Caller), so basically you are calling a function that executes another function of the same contract.

I advice you to read the Inheritance part of the Solidity documentation for the official explanation and more details.

https://solidity.readthedocs.io/en/v0.4.25/contracts.html#inheritance

0

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.