Этот интерфейс просто для удобства, поэтому вы можете легко вызывать методы интерфейса.К этому интерфейсу можно привести любой адрес смарт-контракта, даже если он не является экземпляром этого интерфейса.
Например, если я внесу следующие изменения в ваш пример:
ApproveAndCall.sol
contract ApproveAndCall {
function receiveApproval(address _sender, uint256 _amount, address _addressOfToken, bytes _extraData) external {
emit ReceiveApproval(_sender, _amount, _addressOfToken, _extraData);
}
}
contract ApproveAndCall2 {
function() public {
emit Fallback(msg.data);
}
}
TokenERC20.sol
interface tokenRecipient {
function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external;
}
contract TokenERC20 is Pausable {
function approveAndCall(address _spender, uint256 _value, bytes _extraData) public noReentrancy returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
spender.receiveApproval(msg.sender, _value, this, _extraData);
}
}
Если в качестве * 1016 будет использоваться адрес контракта ApproveAndCall
* параметр, он будет работать, как и ожидалось, потому что соответствующая функция фактически определена в смарт-контракте, поэтому вызывается receiveApproval
.
Однако, если адрес параметра ApproveAndCall2
будет использоваться в качестве параметра _spender
, вместо этого будет вызвана «резервная функция», поскольку функция receiveApproval
не существует в ApproveAndCall2
договор.Переменная msg.data
содержит закодированные calldata для этого вызова функции (имя функции, значения параметров и т. Д.).