как узнать, где находится ссылка интерфейса между реализацией и объявлением в блокчейне ethereum - PullRequest
0 голосов
/ 25 октября 2018

Я не понимаю, как связать объявление интерфейса с частью реализации в твердости

Вот псевдокод, который оставляет только важную часть, которая связана.

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, а tokenRecipient с именем "spender" будет вызывать функцию "receiveApproval".

, но как смарт-контракт TokenERC20 узнает, что реальное "receiveApproval" вызывается "spender""?

Я думаю, что это не похоже ни на какое соединение с адресами или чем-то другим.

Оба умных контракта уже были развернуты в rinkeby testnet.и это все еще, кажется, работает хорошо.

1 Ответ

0 голосов
/ 26 октября 2018

Этот интерфейс просто для удобства, поэтому вы можете легко вызывать методы интерфейса.К этому интерфейсу можно привести любой адрес смарт-контракта, даже если он не является экземпляром этого интерфейса.

Например, если я внесу следующие изменения в ваш пример:

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 для этого вызова функции (имя функции, значения параметров и т. Д.).

...