26

I have seen here and several other places that the correct way to send ether from a contract to an address is to call the .call{}() method.

Then here, I have seen the method being used with arguments, like so:

addr.call{value: msg.value, gas: 5000}(
    abi.encodeWithSignature("foo(string,uint256)", "call foo", 123)
);

I understand the arguments in the curly braces. value: is the eth you want to send and gas: is the amount of gas you are willing to pay for the transaction to be mined (correct me if I am wrong).

What I do not understand are the arguments in brackets.

  1. What is the abi object inside the contract and what does it do? Is it the same as the one you get when you compile the contract?
  2. What does the abi.encodeWithSignature() method do?
  3. How many arguments can the brackets take and what do they mean? And do you have to provide arguments to it or can you leave it empty?

3 Answers 3

21

After doing some research, I finally have the answers to the questions.

1. What is the abi object inside the contract and what does it do? Is it the same as the one you get when you compile the contract?

According to the Solidity docs:

The Contract Application Binary Interface (ABI) is the standard way to interact with contracts in the Ethereum ecosystem, both from outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type, as described in this specification. The encoding is not self describing and thus requires a schema in order to decode.

So the abi object that contains the encodeWithSignature() method is the standard way to interact with contracts in the Ethereum ecosystem.

2. What does the abi.encodeWithSignature() method do?

This method takes either an empty sting or a function signature as its first argument. The function signature is usually a function in the called contract, although when it is not, there are ways Solidity deals with that. When it is a function in the called contract, that function is called when the abi.encodeWithSignature() method is called. So in the code example in the question, the called contract has a function: function foo(string var1, uint256 var2){} that is called every time the abi.encodeWithSignature("foo(string,uint256)", "call foo", 123) method is called in the caller contract. The other two arguments in the abi.encodeWithSignature() are arguments passed to the foo() function when it is being called.

3. How many arguments can the brackets take and what do they mean? And do you have to provide arguments to it or can you leave it empty?

The brackets in the call method, i.e.:

addr.call{value: msg.value, gas: 5000}(/** I am talking about this bracket*/);

requires a single bytes argument. So if you do not want to pass the abi.encodeWithSignature() method, you should pass an empty string or the compiler will throw an error.

1
  • 1
    Just a correction, "that function is called when the abi.encodeWithSignature() method is called" is actually wrong since abi.encodeWithSignature() simply encodes the target method's signature along with its arguments. The actual call is made when you call the method "address(destination).call(abi.encodeWithSignature())". Felt like needing to clarify because this snippet is misleading.
    – Teodoro
    Mar 13, 2022 at 2:00
7
  • address.call(bytes memory msg) accepts a single input parameter: the message to sent to a contract (usually a function call).
  • abi.encodeWithSignature(functionSignature, param1, param2, ...) accepts any number of parameters but the first one is required. It creates a function call message that encodes the function and the parameters.

The code can be written like:

interface IFoo {
    function foo(string, uint256) external payable;
}

IFoo(addr).foo{value: msg.value, gas: 5000}("call foo", 123)

For more details check the documentation https://docs.soliditylang.org/en/v0.8.3/types.html#address

0
  1. How many arguments can the brackets take and what do they mean? And do you have to provide arguments to it or can you leave it empty?

The brackets in the call method, i.e.:

addr.call{value: msg.value, gas: 5000}(/** I am talking about this bracket*/);


{value: msg.value, gas: 5000} : This bracket can take 3 arguments as per the error by the compiler

value, gas and salt.

enter image description here

Value and Gas you had already mentioned in above answers the usage of salt can be understood in context of create2 where we can create a contract using another contract.

Is it possible to deploy a contract using create2 in Solidity?

1
  • As the author precised it, they weren't asking about the first bracket but about the second bracket that takes in either an empty string or a function selector. As for your answer it is actually wrong. The salt is only used for the creation of a new contract with the new [Contract Name] appellation. Not the address.call() method. Just like it was explained in the link you provided.
    – Torof
    Aug 11 at 16:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.