Understanding tx.origin and msg.sender helps you know who started a transaction and who called a function in smart contracts.
Transaction context (tx.origin vs msg.sender) in Blockchain / Solidity
address txOrigin = tx.origin; address msgSender = msg.sender;
tx.origin is the original external account that started the transaction.
msg.sender is the immediate caller of the current function.
function checkOrigin() public view returns (address) {
return tx.origin;
}function checkSender() public view returns (address) {
return msg.sender;
}tx.origin stays the same across calls, but msg.sender changes to the immediate caller.contract Caller {
function callOther(address callee) public {
OtherContract(callee).calledFunction();
}
}
contract OtherContract {
function calledFunction() public view returns (address origin, address sender) {
return (tx.origin, msg.sender);
}
}This program has two contracts. Caller calls OtherContract. When callOther runs, tx.origin is the original user who started the transaction, and msg.sender inside calledFunction is the Caller contract.
pragma solidity ^0.8.0; contract OtherContract { function calledFunction() public view returns (address origin, address sender) { return (tx.origin, msg.sender); } } contract Caller { OtherContract other; constructor(address otherAddress) { other = OtherContract(otherAddress); } function callOther() public view returns (address origin, address sender) { return other.calledFunction(); } }
Never use tx.origin for authorization checks because it can be tricked by phishing attacks.
Use msg.sender to check who called your function directly for better security.
Remember, tx.origin is always an external account, never a contract.
tx.origin is the original external account that started the transaction.
msg.sender is the immediate caller of the current function.
Use msg.sender for secure access control in smart contracts.