如何了解interface';s以太坊区块链的实施和声明之间的联系

如何了解interface';s以太坊区块链的实施和声明之间的联系,interface,grammar,ethereum,solidity,Interface,Grammar,Ethereum,Solidity,我不明白如何将接口声明和实现部分连接在一起 这是一段伪代码,只留下相关的重要部分 ApproveAndCall.sol contract ApproveAndCall { function receiveApproval(address _sender, uint256 _amount, address _addressOfToken, bytes _extraData) external { emit ReceiveApproval(_send

我不明白如何将接口声明和实现部分连接在一起

这是一段伪代码,只留下相关的重要部分

ApproveAndCall.sol

    contract ApproveAndCall {
        function receiveApproval(address _sender, uint256 _amount, address _addressOfToken, bytes _extraData) external {
            emit ReceiveApproval(_sender, _amount, _addressOfToken, _extraData);
        }
    }

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);
        }
    }
正如您所看到的,接口“tokenRecipient”是在TokenERC20.sol中声明的 名为“spender”的令牌接收者将调用函数“receiveApproval”

但TokenERC20智能合约如何知道真正的“接受批准”,即“挥霍者”

我认为这似乎与地址或其他东西没有任何联系


这两个智能合约都已部署在rinkeby testnet上。这个接口只是为了方便起见,所以您可以轻松地调用接口方法。您可以将任何智能合约地址强制转换到此接口,即使它们不是此接口的实例

例如,如果我对您的示例进行以下更改:

批准并调用.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);
    }
}
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);
    }
}
TokenERC20.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);
    }
}
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);
    }
}
如果
批准和调用
合同的地址将用作
\u spender
参数,它将按预期工作,因为智能合同中实际上定义了相应的函数,因此调用了
接收批准

但是,如果将
批准和调用2
合同的地址用作
\u spender
参数,则会调用“回退函数”,因为
批准和调用2
合同上不存在
接收批准
函数。
msg.data
变量包含此函数调用的编码调用数据(函数名、参数值等)