I am following along with a older tutorial on making an ERC20 token in order to learn Solidity a little better.

Since the tutorial is old, I've had to change a lot of things so far to get it up to speed with version 0.8.0 (The version I am working with)

Now I am having an issue with function that is created to approve then call the receiving contract. Below is my code:

  /* Approves and then calls the receiving contract */
function approveAndCall(address _spender, uint256 _value, bytes memory _extraData) public returns (bool success) {
    allowed[msg.sender][_spender] = _value;
    Approval(msg.sender, _spender, _value);

    //call the receiveApproval function on the contract you want to be notified. This crafts the function signature manually so one doesn't have to include a contract in here just for this.
    //receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData)
    //it is assumed that when does this that the call *should* succeed, otherwise one would use vanilla approve instead.
    if(!_spender.call(abi.encode(bytes4(bytes32(keccak256("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData)))
    return true;

The error I am getting is on the IF statement:

TypeError unary operator ! cannot be applied to type tuple(bool, bytes memory)


TypeError tuple(bool, bytes memory) is not implicitly convertible to expected type bool. 

From my understanding call() is outdates and can be eliminated if I just simply use something else? However I am not sure what my other options are here.

If there are no other options, can someone please help me understand what I should be using this call() function for? And how I can implement a fix that would make sense?

Thank you!

1 Answer 1


From 0.5 the syntax for .call has changed. It accepts a single bytes memory parameter and returns a tuple (bool, bytes memory).

That should be written as

(bool success, bytes memory data) = _spender.call(abi.encodeWithSignature("receiveApproval(address,uint256,address,bytes)",
                                      msg.sender, _value, address(this), _extraData));
require(success, "Call failed");


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.