What other constants depend on the current call like msg.sender?












2















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?










share|improve this question





























    2















    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?










    share|improve this question



























      2












      2








      2








      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?










      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 24 at 19:10









      Rob Hitchens

      28.8k74482




      28.8k74482










      asked Jan 24 at 17:53









      Justin HarrisJustin Harris

      1266




      1266






















          3 Answers
          3






          active

          oldest

          votes


















          1














          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.






          share|improve this answer

































            2














            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






            1. 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.






            share|improve this answer
























            • That's very helpful. How about doing stuff like: modifier onlyOwner() { require(msg.sender == owner || tx.origin == owner, "Sender is not the owner."); _; } ? Could that be a problem too?

              – Justin Harris
              Jan 28 at 16:25











            • My understanding is tx.origin can be overwritten by a determined adversary so I've learned to just disregard it and carry on as though it doesn't exist. I would call the example function with otherContact.somethingOnBehalfOfSomeoneElse(msg.sender) so my contract relies exclusively on values I believe are trustworthy.

              – Rob Hitchens
              Jan 28 at 17:00



















            1














            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.






            share|improve this answer
























            • Thanks your answer is very good too but I accepted the other because it gave some details about the use of this.

              – Justin Harris
              Jan 24 at 19:06











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


            }
            });














            draft saved

            draft discarded


















            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









            1














            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.






            share|improve this answer






























              1














              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.






              share|improve this answer




























                1












                1








                1







                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.






                share|improve this answer















                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.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 24 at 19:10

























                answered Jan 24 at 18:49









                ivicaaivicaa

                5,4981938




                5,4981938























                    2














                    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






                    1. 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.






                    share|improve this answer
























                    • That's very helpful. How about doing stuff like: modifier onlyOwner() { require(msg.sender == owner || tx.origin == owner, "Sender is not the owner."); _; } ? Could that be a problem too?

                      – Justin Harris
                      Jan 28 at 16:25











                    • My understanding is tx.origin can be overwritten by a determined adversary so I've learned to just disregard it and carry on as though it doesn't exist. I would call the example function with otherContact.somethingOnBehalfOfSomeoneElse(msg.sender) so my contract relies exclusively on values I believe are trustworthy.

                      – Rob Hitchens
                      Jan 28 at 17:00
















                    2














                    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






                    1. 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.






                    share|improve this answer
























                    • That's very helpful. How about doing stuff like: modifier onlyOwner() { require(msg.sender == owner || tx.origin == owner, "Sender is not the owner."); _; } ? Could that be a problem too?

                      – Justin Harris
                      Jan 28 at 16:25











                    • My understanding is tx.origin can be overwritten by a determined adversary so I've learned to just disregard it and carry on as though it doesn't exist. I would call the example function with otherContact.somethingOnBehalfOfSomeoneElse(msg.sender) so my contract relies exclusively on values I believe are trustworthy.

                      – Rob Hitchens
                      Jan 28 at 17:00














                    2












                    2








                    2







                    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






                    1. 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.






                    share|improve this answer













                    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






                    1. 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.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jan 24 at 19:11









                    Rob HitchensRob Hitchens

                    28.8k74482




                    28.8k74482













                    • That's very helpful. How about doing stuff like: modifier onlyOwner() { require(msg.sender == owner || tx.origin == owner, "Sender is not the owner."); _; } ? Could that be a problem too?

                      – Justin Harris
                      Jan 28 at 16:25











                    • My understanding is tx.origin can be overwritten by a determined adversary so I've learned to just disregard it and carry on as though it doesn't exist. I would call the example function with otherContact.somethingOnBehalfOfSomeoneElse(msg.sender) so my contract relies exclusively on values I believe are trustworthy.

                      – Rob Hitchens
                      Jan 28 at 17:00



















                    • That's very helpful. How about doing stuff like: modifier onlyOwner() { require(msg.sender == owner || tx.origin == owner, "Sender is not the owner."); _; } ? Could that be a problem too?

                      – Justin Harris
                      Jan 28 at 16:25











                    • My understanding is tx.origin can be overwritten by a determined adversary so I've learned to just disregard it and carry on as though it doesn't exist. I would call the example function with otherContact.somethingOnBehalfOfSomeoneElse(msg.sender) so my contract relies exclusively on values I believe are trustworthy.

                      – Rob Hitchens
                      Jan 28 at 17:00

















                    That's very helpful. How about doing stuff like: modifier onlyOwner() { require(msg.sender == owner || tx.origin == owner, "Sender is not the owner."); _; } ? Could that be a problem too?

                    – Justin Harris
                    Jan 28 at 16:25





                    That's very helpful. How about doing stuff like: modifier onlyOwner() { require(msg.sender == owner || tx.origin == owner, "Sender is not the owner."); _; } ? Could that be a problem too?

                    – Justin Harris
                    Jan 28 at 16:25













                    My understanding is tx.origin can be overwritten by a determined adversary so I've learned to just disregard it and carry on as though it doesn't exist. I would call the example function with otherContact.somethingOnBehalfOfSomeoneElse(msg.sender) so my contract relies exclusively on values I believe are trustworthy.

                    – Rob Hitchens
                    Jan 28 at 17:00





                    My understanding is tx.origin can be overwritten by a determined adversary so I've learned to just disregard it and carry on as though it doesn't exist. I would call the example function with otherContact.somethingOnBehalfOfSomeoneElse(msg.sender) so my contract relies exclusively on values I believe are trustworthy.

                    – Rob Hitchens
                    Jan 28 at 17:00











                    1














                    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.






                    share|improve this answer
























                    • Thanks your answer is very good too but I accepted the other because it gave some details about the use of this.

                      – Justin Harris
                      Jan 24 at 19:06
















                    1














                    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.






                    share|improve this answer
























                    • Thanks your answer is very good too but I accepted the other because it gave some details about the use of this.

                      – Justin Harris
                      Jan 24 at 19:06














                    1












                    1








                    1







                    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.






                    share|improve this answer













                    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.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jan 24 at 18:52









                    Lauri PeltonenLauri Peltonen

                    5,8232525




                    5,8232525













                    • Thanks your answer is very good too but I accepted the other because it gave some details about the use of this.

                      – Justin Harris
                      Jan 24 at 19:06



















                    • Thanks your answer is very good too but I accepted the other because it gave some details about the use of this.

                      – Justin Harris
                      Jan 24 at 19:06

















                    Thanks your answer is very good too but I accepted the other because it gave some details about the use of this.

                    – Justin Harris
                    Jan 24 at 19:06





                    Thanks your answer is very good too but I accepted the other because it gave some details about the use of this.

                    – Justin Harris
                    Jan 24 at 19:06


















                    draft saved

                    draft discarded




















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                    Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                    A Topological Invariant for $pi_3(U(n))$