EDIT: Solidity's author, chriseth, recommends to avoid using Solidity's call
https://github.com/ethereum/solidity/issues/2884#issuecomment-329169020
The thing is: a.call()
is an ancient beast that should not be used. I would recommend using inline assembly for such tasks, since it provides the same security guarantees but does not do any invisible magic.
Solidity's call
is a low-level interface for sending a message to a contract. It returns false
if the subcall encounters an exception, otherwise it returns true
. There is no notion of a legal call, if it compiles, it's valid Solidity.
nameReg.call("register", "MyName")
is a message that passes certain bytes to nameReg. For the bytes, see: Understanding nameReg.call("register", "MyName") style call between contracts
nameReg.call(bytes4(sha3("fun(uint256)")), a)
is a message that would invoke a function named fun
(if nameReg adheres to the ABI) and pass it the raw, unpadded data a
(you need to correctly pad a
to 32 bytes first if you want behavior to match the ABI. For uint256
use left-padding.).
For 3, contract.call.value(...)(...)
is a way to add Ether when invoking a contract. if(!nameReg.call.value(10)()){throw;}
is an example of handling the failure case of the subcall. Note the extra parentheses value(10)()
which invokes the fallback function.
call
is a low-level interface, and it is simpler to invoke a function directly, nameReg.fun(a)
instead of the second example. The direct invocation is also type-safe, and allows the return value of fun
to be used.