Solidity: who the heck is msg.sender?
Here we will shortly discuss how the msg.sender
mechanism works. As usual we will experiment with small chunks of Solidity that you will be able to run in your browser
At the core of the blockchain is the mechanism of adding blocks of transactions to the chain of blocks: this is the job carried out by the miners that keep the state of the Ethereum Virtual Machine (EVM) consistent; miners are in a competition to append transactions to blocks.
The state of the EVM is the effect of the execution of all the transactions collected in blocks: in a way Ethereum (and blockchains in general) are a distributed log file that collect the result of operations performed by smart contracts. Another way is to consider the blockchain as a globally shared, transactional database.
Operations on smart contracts are ignited by a simple mechanism of sending gas to an address, if the address is a smart contract it will produce an invocation of a method whose name is hashed within the transaction payload. following an example of how to invoke a method store(uint256)
on a smart contract with the parameter 1:
What really happens in a transaction containing a method invocation is that the method signature, store(uint256)
is hashed with keccak256 and the first 4 bytes are packed together with the arguments; this sequence of bytes is the content of the input field in the transaction above. More complex parameters (e.g. strings, arrays etc..) are packed in a sensible way by serializing them and concatenating together with the function hash.
In depth analysis can be found here but, for the sake of the clarity of this article, the sense of this packing is to have a compact representation of the function name together with all the parameters and this is what you find in the input field of the transaction in Remix and you also find it decoded in the inspector.
The sender of the transaction
Among the fields of each of the transactions, in Remix, you may notice the field from which is the originating account of the transaction. In Remix it is pretty straightforward to notice how the content of this field matches exactly with the field Account, on the left (see next figure)
This mechanism is quite easy but in the Ethereum specification there are two different functions to access, in Solidity, to the sender of a transaction: msg.sender
and tx.origin
. A couple of simple functions allows you to check that both functions returns exactly the same value.
Are they redundant? Not at all, there is a difference, and can be emphasized in the section.
A simple smart contract to show the difference
The difference between the two is thatmsg.sender
contains the address that has originated the call while tx.origin
contains the originator of the transaction. To clarify the way the two variables work you can use the following piece of code, ready to be tested right in Remix.
The source contains two different contracts, one called Storage
the other one is Caller
and contains an instance of Storage
in the field StorageObject
.
The instance of Storage
is created in the constructor of Caller
(line 28).
Both contracts contain the same functions that will return the content of msg.sender
and the content of tx.origin
. But what really will shed light on the difference are the two methods (line 34 and 42): they will return the content of msg.sender
and tx.origin
from the point of view of the instance of Storage
.
As usual the test is more explanatory than words describing it:
What you can see here is: the tx.origin
contains the same value in both contracts, Storage with the function inspectOrigin
and Caller
with the function inspectInspectOrigin
, because for both the originator of the call is the account 0x5B38...C4
. You may notice the difference with the result of inspectSender
and inspectInspectSender
, they both return the msg.sender
but, respectively, for Caller
and Storage
the result is different, as expected. For Caller
the msg.sender
(function inspectSender
) is, again, the account 0x5B38...C4
while for the smart contract Storage
it is the address 0x9d7f...99
, which is the address of the smart contract Caller
.
The documentation (you can find it here) is simple but it is always interesting to check what really happens under the hood.
Join Coinmonks Telegram group and learn about crypto trading and investing