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?

msg.sender will be the contract calling the contract.

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

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.

  • Spoofed? At the protocol level, or at the application level (e.g. an oracle)? – Jesse Busman Oct 21 '17 at 21:00
  • 2
    Better if I refer to sources: github.com/ethereum/solidity/issues/683 – Rob Hitchens Oct 21 '17 at 21:11
  • 1
    Spoofed seems to be incorrect here. Yes, there are criticism to its use, but spoofable is nowhere in the issue. – Fabiano Soriani Jul 10 at 20:04
  • 1
    "Spoof" is the wrong word for a contract impersonating someone else to a contract that relies on tx.origin? – Rob Hitchens Jul 10 at 23:33

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

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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