I've been going through the official Ethereum token tutorial and I noticed that the provided token code includes the following lines within the approveAndCall
function:
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
I'm confused how this works and what it does. Given that tokenRecipient
is an interface [0] without a corresponding implementation, how can and why does approveAndCall
call tokenRecipient
's constructor and its receiveApproval
method? While I can imagine that unimplemented interfaces like tokenRecipient
might have default constructors and no-op implementations, I still don't see why approveAndCall
would then call receiveApproval
on the returned tokenRecipient
contract.
At first, I was thinking that Solidity had copied Go and allowed implicit interface implementation i.e. if a contract and interface have matching methods and signatures, the contract implements that interface. But even that doesn't explain this case because the token contracts in this tutorial don't include receiveApproval
implementations and therefore aren't implicitly implementing the tokenRecipient
interface.
The only other option I can think of is that we're assuming that there's a tokenRecipient
implementation that corresponds to the address passed in to approveAndCall
as _spender
. Is that what's happening? If so, I wish the tutorial made that more clear.
[0] tokenRecipient
has the following signature.
interface tokenRecipient {
function receiveApproval(
address _from, uint256 _value, address _token, bytes _extraData
) public;
}