address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
nameReg.call("register", "MyName"); //1
nameReg.call(bytes4(sha3("fun(uint256)")), a); //2
if(!nameReg.call.value(10)){throw;} //3
Here it says,
Furthermore, to interface with contracts that do not adhere to the
ABI, the function call is provided which takes an arbitrary number of
arguments of any type. These arguments are padded to 32 bytes and
concatenated. One exception is the case where the first argument is
encoded to exactly four bytes. In this case, it is not padded to allow
the use of function signatures here.
- Are 1 and 2 legal?
- Does it mean that 2 is illegal?
- What does the 3 mean?
Best Answer
Solidity's
call
is a low-level interface for sending a message to a contract. It returnsfalse
if the subcall encounters an exception, otherwise it returnstrue
. 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 contractsnameReg.call(bytes4(sha3("fun(uint256)")), a)
is a message that would invoke a function namedfun
(if nameReg adheres to the ABI) and pass it the raw, unpadded dataa
(you need to correctly pada
to 32 bytes first if you want behavior to match the ABI. Foruint256
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 parenthesesvalue(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 offun
to be used.