tx.origin and msg.sender

Published by Mario Oettler on

In some cases, it is important to know who sent a transaction or message to a smart contract. For that reason, Solidity gives us two functions – msg.sender and tx.origin.

tx.origin

tx.origin refers to the EOA that created the initial transaction. This global value is passed along different function calls to other contracts.

msg.sender

msg.sender tells us the last instance from where a function is called. This can be an EOA or a contract. If an EOA sends a transaction to contract A, contract A sees the address of the EOA as msg.sender. If contract A sends a message (e. g. call) to contract B, B sees contract A’s address when looking at msg.sender.

The following figure shows what each contract gets with msg.sender and tx.origin.

Do Not Use tx.origin for Authorization

tx.origin should not be used for authorization. If, for example, the owner was set with

address owner = msg.sender;

but the access check of a function is done with

require(owner == tx.origin);

this could be exploited.

The attacker could trick you into sending some Ether to its contract. Then it makes a call to the contract that is “secured” with require(owner == tx.origin). The check results in true because your EOA address is passed here.

If your contract would have checked msg.sender instead, it would have a false evaluation and deny access.

Categories: