Example in this scenario I guess selfdestruct
will never get called (also: contract A isn't so important by the way just focus on B onward):
in Contract A:
address contractb = 0x....;
function sending() {
contractb.call.value(1 ether)();
}
in Contract B:
address contractc = 0x...;
function () public payable {
if (!contractc.send(msg.value)) {
throw;
}
if (!contractc.send(0)) {
throw;
}
}
in Contract C:
address someone = 0x...;
function () public payable {
selfdestruct(someone);
}
In short:
- Contract A sends ether to B using
call
to have lots of gas... - B forwards the money further to C, the first time it tries it succeeds but C selfdestructs; The 2nd time it fails since C is selfdestructed...
- throw should revert to a state without changes, but how can it revert a selfdesctructed contract?
I guess (and I am 99% sure what will happen...about to test now on Ropsten...): nothing will ever reach C since before any execution revert will check if anything can fail and if it can it reverts - speaking of which how can revert be so sure? What if transaction simply lacks gas to be mined say like 3 gas in call.gas(3).value(1)()
- surely this will not get mined and maybe revert
will prevent anything until mining happens? Thanx!
selfdestruct
operation can complete successfully in this scenario (it would need some gas I suppose, but the function has a stipend of only 2300 units). 2. If it does complete successfully, then your 2nd attempt should fail in a manner similar to callingx.send(msg.value)
, wherex
is some bogus address of a non-contract (zero address would probably "do the job" here). So you should end up with the same type of revert IMO.and the former contract is now just a regular wallet
- not unless you miraculously have the private key of that former contract.