3.14 Transaction Checks
tx.origin
tx.origin
The use of tx.origin
is considered dangerous in certain situations within smart contracts. Remember that in the context of Ethereum, tx.origin
gives the address of the externally owned account that originated the transaction.
If the tx.origin
address is used for authorization, then it can be abused by attackers to launch replay attacks by coming in between the user and the smart contract of concern.
This is sometimes known as "man in the middle replay attack" (or MITM as an abbreviation) because the attacker comes in between the user and the contract, captures the transaction and later replaces it. Because the smart contract uses tx.origin
, it fails to recognize that this transaction actually was originated from the attacker in the middle.
So in this case the recommended best practice for smart contracts using authorization is to use msg.sender
instead of tx.origin
, because msg.sender
would give the address of the most recent or the closest entity. So in this case, if there is a man in the middle attacker, then msg.sender
would give the address of the attacker and not that of the authorized user pointed to by tx.origin
.
Contract Check
There may be situations where a particular smart contract may want to know, if the transaction or the call made to it is coming from a contract account or an externally owned account.
There are two popular ways for determining that:
Checking if the code size of the account of the originating transaction is greater than zero and if this is not zero, it means that that account has code and therefore is a contract account.
Checking if the
msg.sender
is the same as thetx.origin
and, if it is, then it means that themsg.sender
is an externally owned account.
Remember that tx.origin
can only be an externally owned account in Ethereum as of now.
So these two techniques have pros and cons and depending on the specific application it may make more sense to use one over the other.
There are risks associated and implications thereof of either of these two approaches particularly with the code size approach the risk is that, if this check is made while a contract is still being constructed within the constructor the code size will still be zero for that account so, if we determine based on that aspect that this is an externally owned account, then it would be a wrong assumption.
Last updated