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












3















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









New contributor




Justin Harris is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

























    3















    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









    New contributor




    Justin Harris is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      3












      3








      3








      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









      New contributor




      Justin Harris is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.












      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









      New contributor




      Justin Harris is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      Justin Harris is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 22 mins ago









      Rob Hitchens B9lab

      26.8k64480




      26.8k64480






      New contributor




      Justin Harris is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 1 hour ago









      Justin HarrisJustin Harris

      1185




      1185




      New contributor




      Justin Harris is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Justin Harris is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Justin Harris is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          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

































            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
              27 mins ago



















            1














            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























              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.










              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 23 mins ago

























                  answered 44 mins ago









                  ivicaaivicaa

                  4,843836




                  4,843836























                      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
                        27 mins ago
















                      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
                        27 mins ago














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

















                      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











                      1














                      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




























                        1














                        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


























                          1












                          1








                          1







                          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 22 mins ago









                          Rob Hitchens B9labRob Hitchens B9lab

                          26.8k64480




                          26.8k64480






















                              Justin Harris is a new contributor. Be nice, and check out our Code of Conduct.










                              draft saved

                              draft discarded


















                              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.




                              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

                              How to label and detect the document text images

                              Vallis Paradisi

                              Tabula Rosettana