I'm trying to wrap my head around the approveAndCall() function, because I want to allow users to pay for functions of my main contract with the associated tokens.

I'm trying to understand the example of this article. In the "approveAndCall()" section, the following functions are shown:

function approveAndCall(address _recipient,
                    uint256 _value,
                    bytes _extraData) {
  approve(_recipient, _value);


function receiveApproval(address _sender,
                         uint256 _value,
                         TokenContract _tokenContract,
                         bytes _extraData) {
  require(_tokenContract == tokenContract);
  require(tokenContract.transferFrom(_sender, address(this), 1));
  uint256 payloadSize;
  uint256 payload;
  assembly {
    payloadSize := mload(_extraData)
    payload := mload(add(_extraData, 0x20))
  payload = payload >> 8*(32 - payloadSize);
  info[sender] = payload;

What does the assembly part in the second function do?

The example function stores data, so all the actual function called via the token contract does is info[sender] = payload;. Do I need a payload if I replace it with my function that only has "simple" arguments? (No bytes, just uints, addresses, etc.) Do they need to be converted to bytes?

(I might ask a different question for more details about approveAndCall() and recieveApproval, for now I'd just want to understand that payload part.)

1 Answer 1


No, you do not need the code related to the payload. You can modify the function and remove the bytes _exrtaData or just pass a random value there.

The reciveApproval just need to execute transferFrom(address from, address to, uint value) to move the tokens approved.

For the assembly, well, it seem to be very specific. You can see here about mload instruction.

mload(0xAB) loads the data stored in the location 0XAB. The instructions seem to reflect a particular application in which the contract receive a memory position (_extraData) in which information about the size of the data is stored. Then in a position _extraData + 0x20 there is the data which is modified by doing a right shift operation and then the result is stored in info (I have no idea about the purpose of this)

I hope this helps

EDIT after OP comment.

If you will have receiveApproval behavior to depend of what the subject wants to do, you can ask them to pass an extra parameter like this:

function receiveApproval(address _sender, uint256 _value, TokenContract _tokenContract, string param) public {
    require(tokenContract.transferFrom(_sender, address(this), _value));
    if (param == 'your_first_code'){
        //do something
    if (param == 'your_second_code'){
        //do something
    // more conditional as functions you have
  • Thanks. So what do I write in receiveApproval? I can't write instructions directly, because I want to be able to call different functions. Do I have to write as many approveAndCall and receiveApproval as I have functions? Apr 10, 2018 at 15:47
  • I updated the answer. You could have only one approveAndCall and ask for an extra parameter that defines what function should be executed in your contract. I wrote an example of this in the answer. Let me know how it goes.
    – Jaime
    Apr 10, 2018 at 16:09
  • So, because it's in my service contract and not my token contract, in the ifs I can call my function directly, right? Like if (function_code == 1) { function1(arg1, arg2); } else if (function_code == 2) { function2(arg3); } Apr 11, 2018 at 9:31
  • Yes, this is now in your contract so you can call the functions directly
    – Jaime
    Apr 11, 2018 at 12:34
  • A lot of things are still blurry. Is recipient the service contract address? If not, where do I put the contract address? Apr 12, 2018 at 9:28

Your Answer

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

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