1

When we call a function on an external contract, the evm computes a bytes buffer which contains the function signature and arguments.

There are 2 ways to serialize arguments: abi.encode and abi.encodePacked. The difference between this 2 methods are well documented and i have understood them.

What i want to understand is why there are this 2 methods ? Nobody says when we should use the first and when we should use the second.

How can i see which method is used when i make this calls:

Call 1:

(success, ) = address(c).call(abi.encodeWithSignature("myfunction(uint256,uint256)", 400,500));

Call 2:

(success, ) = address(c).call(abi.encodeWithSelector(bytes4(keccak256("myfunction(uint256,uint256)")), 400,500)  )

Call 3:

(success, ) = address(c).call(  bytes4(keccak256("myfunction(uint256,uint256)")),    400, 500);

Call 4:

contract_instance.myfunction(400,500);

Thanks a lot

1

I'd recommend to use 4 at all times if possible. It is easy to remember and write. The behavior is that it will revert the whole transaction if the call fails, which is the most reasonable alternative in general.

  • abi.encode encode its parameters using the ABI specs. The ABI was designed to make calls to contracts. Parameters are padded to 32 bytes. If you are making calls to a contract you likely have to use abi.encode

  • abi.encodePacked encode its parameters using the minimal space required by the type. Encoding an uint8 it will use 1 byte. It is used when you want to save some space, and not calling a contract.

  • abi.encodeWithSignature same as encode but with the function signature as first parameter. Use when the signature is known and don't want to calculate the selector.

  • abi.encodeWithSelector same as encode but selector is the first parameter. It almost equal to encodeWithSignature, use whatever fits best.

Case 3 was deprecated do not use, call+abi.encode should do the same job.

2
  • Thanks a lot. So you mean abi.encodePacked is not used in my 4 calls example ? abi.encodePacked is used manually when i want to serialize values for another usage than function calls ? – Bob5421 Jan 3 at 19:30
  • @Bob5421 When calling a function directly in solidity the compiler generate code similar to abi.encode. The function abi.encodePacked is mostly used to serialize things, like in signatures messages for example. It can be used for functions calls but you should ensure the data layout generated matches the expected by the function. – Ismael Jan 3 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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