通过tx.origin授权(Authorization Through tx.origin)
tx.origin(原始交易发起者的外部地址)是一个全局变量,它返回发送交易的地址。重要的是千万不要使用tx.origin,因为另一个合约会使用fallback函数来调用你的合约并获得授权,授权地址存储在tx.origin中。
考虑以下案例,首先你部署了一个TxUserWallet合约:
// This contract contains a bug - do not use
contract TxUserWallet {
address owner;
constructor() public {
owner = msg.sender;
}
function transferTO(address payable dest, uint amount) public {
require(tx.origin == owner);
dest.transfer(amonut);
}
}
上述我们可以看出TxUserWallet通过tx.origin授权了transferTO()。
然后是攻击合约TxAttackWallet:
interface TxUserWallet {
function transferTo(address payable dest, uint amount) external;
}
contract TxAttackWallet {
address payable owner;
constructor() public {
owner = msg.sender;
}
function() external {
TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);
}
}
如果有人现在欺骗你向TxAttackWallet合约地址发送ETH,攻击者可以检查tx.origin找到发送交易的地址来窃取你的资金。
所以为了防止这种攻击的发生,一般使用msg.sender。