EDIT Dec 2019: call.value()()
should now be used for transferring ether.
See: Is transfer() still safe after the Istanbul update?
The following is the original answer.
contract.call.gas(...).value(...)(...)
is a way to add Ether and limit gas when invoking a contract. Basically, TheDAO used call.value
to move Ether around in a generic way.
contract.call.value(...)()
will invoke the fallback function at contract
with almost all the gas that the caller has. In a normal call like contract.foo
, if contract
is untrusted, it is much clearer that untrusted code (foo
) is explicitly being invoked.
Another important difference is that any exceptions in contract.foo
will bubble up: if foo
runs Out of Gas, that exception immediately halts the transaction and reverts all state changes. With contract.call.value(...)()
, only a true or false is returned (the exception does not bubble up) and so you generally see code like if (!contract.call.value(...)()) throw;
Here's a glimpse into how the reentrant attack was performed: How was the recursion created that lead to theDAO hack?.