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
msg.sender will be the contract calling the contract.
tx.origin will be the account that initiated the chain of contract calls.
- 10,478
- 6
- 35
- 62
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.
- 55,151
- 11
- 89
- 145
-
2Spoofed? At the protocol level, or at the application level (e.g. an oracle)? – Jesbus Oct 21 '17 at 21:00
-
3Better if I refer to sources: https://github.com/ethereum/solidity/issues/683 – Rob Hitchens Oct 21 '17 at 21:11
-
3Spoofed seems to be incorrect here. Yes, there are criticism to its use, but spoofable is nowhere in the issue. – Fabiano Soriani Jul 10 '18 at 20:04
-
2"Spoof" is the wrong word for a contract impersonating someone else to a contract that relies on
tx.origin? – Rob Hitchens Jul 10 '18 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. – Garen Vartanian Nov 12 '18 at 19:04 -
"when you're interested in the user identity but security isn't a concern" maybe for events that are only used on a front end to display user history or something ? – Oli Crt Sep 29 '22 at 16:00
-
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 Jan 05 '23 at 18:00
Caller -> ContractA -> ContractB
Contract A is msg.sender in ContractB's case
- 18,036
- 20
- 54
- 82
- 693
- 2
- 10
- 17
-
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 Jan 05 '23 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();
}
}
- 10,478
- 6
- 35
- 62
- 41
- 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
- 10,478
- 6
- 35
- 62
- 304
- 1
- 6
msg.senderis the address that is deploying the contract. – Jesbus Nov 14 '18 at 15:14