What other constants depend on the current call like msg.sender?
I recently noticed that msg.sender
isn't always the original caller's address (see here). It's the address of the current call. So if foo()
calls bar()
, then msg.sender
in bar()
will be the address of the contract containing foo()
.
My questions are:
- Are there any other constants that depend on the current call? Full list: https://solidity.readthedocs.io/en/latest/units-and-global-variables.html#special-variables-and-functions
- What's the best way to get the original sender's address?
contract-design contract-invocation constant
New contributor
add a comment |
I recently noticed that msg.sender
isn't always the original caller's address (see here). It's the address of the current call. So if foo()
calls bar()
, then msg.sender
in bar()
will be the address of the contract containing foo()
.
My questions are:
- Are there any other constants that depend on the current call? Full list: https://solidity.readthedocs.io/en/latest/units-and-global-variables.html#special-variables-and-functions
- What's the best way to get the original sender's address?
contract-design contract-invocation constant
New contributor
add a comment |
I recently noticed that msg.sender
isn't always the original caller's address (see here). It's the address of the current call. So if foo()
calls bar()
, then msg.sender
in bar()
will be the address of the contract containing foo()
.
My questions are:
- Are there any other constants that depend on the current call? Full list: https://solidity.readthedocs.io/en/latest/units-and-global-variables.html#special-variables-and-functions
- What's the best way to get the original sender's address?
contract-design contract-invocation constant
New contributor
I recently noticed that msg.sender
isn't always the original caller's address (see here). It's the address of the current call. So if foo()
calls bar()
, then msg.sender
in bar()
will be the address of the contract containing foo()
.
My questions are:
- Are there any other constants that depend on the current call? Full list: https://solidity.readthedocs.io/en/latest/units-and-global-variables.html#special-variables-and-functions
- What's the best way to get the original sender's address?
contract-design contract-invocation constant
contract-design contract-invocation constant
New contributor
New contributor
edited 22 mins ago
Rob Hitchens B9lab
26.8k64480
26.8k64480
New contributor
asked 1 hour ago
Justin HarrisJustin Harris
1185
1185
New contributor
New contributor
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
msg.data
, msg.sender
, msg.sig
, and msg.value
will depend on the current call.
tx.origin
is the original sender of the transaction (EOA = Externally Owned Account).
Note that the msg.*
variables are only changed if you have
this.fn()
or
someOtherContractRef.fn()
Internal calls within the contract (without this.
) will not change msg.*
variables.
add a comment |
All of the msg
constants depend on the currenct scope (contract). Their value remains the same in the same contract (even in different functions) but if you call another contract the values change accordingly.
You can see them here in action:
pragma solidity ^0.5.0;
contract A {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function a() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
b();
B b = new B();
b.c();
}
function b() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
contract B {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function c() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
As for the original sender, you can simply use tx.origin
. Note that this is very rarely used as using it may ruin functionality of some proxy contracts etc.
Thanks your answer is very good too but I accepted the other because it gave some details about the use ofthis
.
– Justin Harris
27 mins ago
add a comment |
Adding to @ivicaa's and @Lauri's answer.
What's the best way to get the original sender's address?
tx.origin
is a security concern and not recommended. Relying on it also ensures that contracts cannot be clients of your contract since a contract can never be the tx.origin. This limitation seriously constrains your dapp since it includes multi-signature wallet contracts and since there are usually desirable use-cases where the "user" could be another contract.
It's not a simple issue. This thread may shed some light on the considerations: https://github.com/ethereum/solidity/issues/683
tx.origin
is almost never useful. This is the most subjective point, but I have yet to come across a use of tx.origin that seemed legitimate to me. I welcome counter-examples, but I've written dozens or hundreds of smart contracts without needing it, and I have never heard of anyone else needing it either.
Instead, pass the msg.sender
into functions that are concerned with the transaction signer. This implies that the called contract trusts the sending contract to tell the truth. The called contract should not naively listen to anything, but rather trust only whitelisted contracts that form part of your system.
function somethingOnBehalfOfSomeoneElse(address user) public onlyTrustedContracts {...
Hope it helps.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "642"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Justin Harris is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fethereum.stackexchange.com%2fquestions%2f66082%2fwhat-other-constants-depend-on-the-current-call-like-msg-sender%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
msg.data
, msg.sender
, msg.sig
, and msg.value
will depend on the current call.
tx.origin
is the original sender of the transaction (EOA = Externally Owned Account).
Note that the msg.*
variables are only changed if you have
this.fn()
or
someOtherContractRef.fn()
Internal calls within the contract (without this.
) will not change msg.*
variables.
add a comment |
msg.data
, msg.sender
, msg.sig
, and msg.value
will depend on the current call.
tx.origin
is the original sender of the transaction (EOA = Externally Owned Account).
Note that the msg.*
variables are only changed if you have
this.fn()
or
someOtherContractRef.fn()
Internal calls within the contract (without this.
) will not change msg.*
variables.
add a comment |
msg.data
, msg.sender
, msg.sig
, and msg.value
will depend on the current call.
tx.origin
is the original sender of the transaction (EOA = Externally Owned Account).
Note that the msg.*
variables are only changed if you have
this.fn()
or
someOtherContractRef.fn()
Internal calls within the contract (without this.
) will not change msg.*
variables.
msg.data
, msg.sender
, msg.sig
, and msg.value
will depend on the current call.
tx.origin
is the original sender of the transaction (EOA = Externally Owned Account).
Note that the msg.*
variables are only changed if you have
this.fn()
or
someOtherContractRef.fn()
Internal calls within the contract (without this.
) will not change msg.*
variables.
edited 23 mins ago
answered 44 mins ago
ivicaaivicaa
4,843836
4,843836
add a comment |
add a comment |
All of the msg
constants depend on the currenct scope (contract). Their value remains the same in the same contract (even in different functions) but if you call another contract the values change accordingly.
You can see them here in action:
pragma solidity ^0.5.0;
contract A {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function a() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
b();
B b = new B();
b.c();
}
function b() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
contract B {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function c() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
As for the original sender, you can simply use tx.origin
. Note that this is very rarely used as using it may ruin functionality of some proxy contracts etc.
Thanks your answer is very good too but I accepted the other because it gave some details about the use ofthis
.
– Justin Harris
27 mins ago
add a comment |
All of the msg
constants depend on the currenct scope (contract). Their value remains the same in the same contract (even in different functions) but if you call another contract the values change accordingly.
You can see them here in action:
pragma solidity ^0.5.0;
contract A {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function a() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
b();
B b = new B();
b.c();
}
function b() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
contract B {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function c() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
As for the original sender, you can simply use tx.origin
. Note that this is very rarely used as using it may ruin functionality of some proxy contracts etc.
Thanks your answer is very good too but I accepted the other because it gave some details about the use ofthis
.
– Justin Harris
27 mins ago
add a comment |
All of the msg
constants depend on the currenct scope (contract). Their value remains the same in the same contract (even in different functions) but if you call another contract the values change accordingly.
You can see them here in action:
pragma solidity ^0.5.0;
contract A {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function a() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
b();
B b = new B();
b.c();
}
function b() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
contract B {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function c() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
As for the original sender, you can simply use tx.origin
. Note that this is very rarely used as using it may ruin functionality of some proxy contracts etc.
All of the msg
constants depend on the currenct scope (contract). Their value remains the same in the same contract (even in different functions) but if you call another contract the values change accordingly.
You can see them here in action:
pragma solidity ^0.5.0;
contract A {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function a() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
b();
B b = new B();
b.c();
}
function b() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
contract B {
event Data(bytes a);
event Sig(bytes4 a);
event Val(uint a);
function c() public payable {
emit Data(msg.data);
emit Sig(msg.sig);
emit Val(msg.value);
}
}
As for the original sender, you can simply use tx.origin
. Note that this is very rarely used as using it may ruin functionality of some proxy contracts etc.
answered 41 mins ago
Lauri PeltonenLauri Peltonen
4,9682424
4,9682424
Thanks your answer is very good too but I accepted the other because it gave some details about the use ofthis
.
– Justin Harris
27 mins ago
add a comment |
Thanks your answer is very good too but I accepted the other because it gave some details about the use ofthis
.
– Justin Harris
27 mins ago
Thanks your answer is very good too but I accepted the other because it gave some details about the use of
this
.– Justin Harris
27 mins ago
Thanks your answer is very good too but I accepted the other because it gave some details about the use of
this
.– Justin Harris
27 mins ago
add a comment |
Adding to @ivicaa's and @Lauri's answer.
What's the best way to get the original sender's address?
tx.origin
is a security concern and not recommended. Relying on it also ensures that contracts cannot be clients of your contract since a contract can never be the tx.origin. This limitation seriously constrains your dapp since it includes multi-signature wallet contracts and since there are usually desirable use-cases where the "user" could be another contract.
It's not a simple issue. This thread may shed some light on the considerations: https://github.com/ethereum/solidity/issues/683
tx.origin
is almost never useful. This is the most subjective point, but I have yet to come across a use of tx.origin that seemed legitimate to me. I welcome counter-examples, but I've written dozens or hundreds of smart contracts without needing it, and I have never heard of anyone else needing it either.
Instead, pass the msg.sender
into functions that are concerned with the transaction signer. This implies that the called contract trusts the sending contract to tell the truth. The called contract should not naively listen to anything, but rather trust only whitelisted contracts that form part of your system.
function somethingOnBehalfOfSomeoneElse(address user) public onlyTrustedContracts {...
Hope it helps.
add a comment |
Adding to @ivicaa's and @Lauri's answer.
What's the best way to get the original sender's address?
tx.origin
is a security concern and not recommended. Relying on it also ensures that contracts cannot be clients of your contract since a contract can never be the tx.origin. This limitation seriously constrains your dapp since it includes multi-signature wallet contracts and since there are usually desirable use-cases where the "user" could be another contract.
It's not a simple issue. This thread may shed some light on the considerations: https://github.com/ethereum/solidity/issues/683
tx.origin
is almost never useful. This is the most subjective point, but I have yet to come across a use of tx.origin that seemed legitimate to me. I welcome counter-examples, but I've written dozens or hundreds of smart contracts without needing it, and I have never heard of anyone else needing it either.
Instead, pass the msg.sender
into functions that are concerned with the transaction signer. This implies that the called contract trusts the sending contract to tell the truth. The called contract should not naively listen to anything, but rather trust only whitelisted contracts that form part of your system.
function somethingOnBehalfOfSomeoneElse(address user) public onlyTrustedContracts {...
Hope it helps.
add a comment |
Adding to @ivicaa's and @Lauri's answer.
What's the best way to get the original sender's address?
tx.origin
is a security concern and not recommended. Relying on it also ensures that contracts cannot be clients of your contract since a contract can never be the tx.origin. This limitation seriously constrains your dapp since it includes multi-signature wallet contracts and since there are usually desirable use-cases where the "user" could be another contract.
It's not a simple issue. This thread may shed some light on the considerations: https://github.com/ethereum/solidity/issues/683
tx.origin
is almost never useful. This is the most subjective point, but I have yet to come across a use of tx.origin that seemed legitimate to me. I welcome counter-examples, but I've written dozens or hundreds of smart contracts without needing it, and I have never heard of anyone else needing it either.
Instead, pass the msg.sender
into functions that are concerned with the transaction signer. This implies that the called contract trusts the sending contract to tell the truth. The called contract should not naively listen to anything, but rather trust only whitelisted contracts that form part of your system.
function somethingOnBehalfOfSomeoneElse(address user) public onlyTrustedContracts {...
Hope it helps.
Adding to @ivicaa's and @Lauri's answer.
What's the best way to get the original sender's address?
tx.origin
is a security concern and not recommended. Relying on it also ensures that contracts cannot be clients of your contract since a contract can never be the tx.origin. This limitation seriously constrains your dapp since it includes multi-signature wallet contracts and since there are usually desirable use-cases where the "user" could be another contract.
It's not a simple issue. This thread may shed some light on the considerations: https://github.com/ethereum/solidity/issues/683
tx.origin
is almost never useful. This is the most subjective point, but I have yet to come across a use of tx.origin that seemed legitimate to me. I welcome counter-examples, but I've written dozens or hundreds of smart contracts without needing it, and I have never heard of anyone else needing it either.
Instead, pass the msg.sender
into functions that are concerned with the transaction signer. This implies that the called contract trusts the sending contract to tell the truth. The called contract should not naively listen to anything, but rather trust only whitelisted contracts that form part of your system.
function somethingOnBehalfOfSomeoneElse(address user) public onlyTrustedContracts {...
Hope it helps.
answered 22 mins ago
Rob Hitchens B9labRob Hitchens B9lab
26.8k64480
26.8k64480
add a comment |
add a comment |
Justin Harris is a new contributor. Be nice, and check out our Code of Conduct.
Justin Harris is a new contributor. Be nice, and check out our Code of Conduct.
Justin Harris is a new contributor. Be nice, and check out our Code of Conduct.
Justin Harris is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Ethereum Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fethereum.stackexchange.com%2fquestions%2f66082%2fwhat-other-constants-depend-on-the-current-call-like-msg-sender%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown