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
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.
-
2Spoofed? At the protocol level, or at the application level (e.g. an oracle)?– JesbusCommented Oct 21, 2017 at 21:00
-
3Better if I refer to sources: github.com/ethereum/solidity/issues/683 Commented Oct 21, 2017 at 21:11
-
3Spoofed 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 -
2For 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
msg.sender
will be the contract calling the contract.
tx.origin
will be the account that initiated the chain of contract calls.
-
9To add to this: Inside a contract's constructor,
msg.sender
is the address that is deploying the contract.– JesbusCommented 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...– JimCommented Jan 5, 2023 at 18:00
-
1
Caller -> ContractA -> ContractB
Contract A is msg.sender
in ContractB's case
-
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...– JimCommented Jan 5, 2023 at 18:00
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();
}
}
@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