Я пишу свой собственный смарт-контракт и хочу вызвать функцию из уже развернутого контракта. Фрагмент моего кода:
function myFunc(address _contractAddress, address _user, uint _price) onlyOwner {
//... some code ...
require(_contractAddress.call(bytes4(sha3("func(address, uint256)")), _user, _price));
//... some code ...
}
Я использую Remix IDE. Он показывает мне это предупреждение:
использование «вызова»: по возможности следует избегать использования «вызова» низкого уровня. Это может привести к неожиданному поведению, если возвращаемое значение не обрабатывается должным образом. Используйте прямые вызовы, указав интерфейс вызываемого контракта.
Как мне решить эту проблему? Delegatecall выдает аналогичное предупреждение. Может быть, есть другие способы вызова функции другого контракта?
В новых версиях Solidity можно использовать либо абстрактные контракты , либо интерфейсы .
abstract
ключевом слове для правильной компиляции и virtual
модификаторе в функциях.Я почти уверен, что интерфейсы представлены на низком уровне абстрактными контрактами со всеми внешними виртуальными функциями и без внутренних полей данных.
MyContract.sol:
// SPDX-License-Identifier: Unlicense
pragma solidity >0.8.5;
abstract contract OtherContract {
function otherMethod(address _to, uint _price) external virtual;
}
interface OtherContractInterface {
function otherMethod(address _to, uint _price) external;
}
contract MyContract {
uint public unitPrice = 100;
function myMethod(address _destination, uint _count) external {
// _destination is a contract that implements OtherContract
// this uses the interface.
OtherContractInterface oci = OtherContractInterface(_destination);
oci.otherMethod(address(this), _count * unitPrice);
// this code uses the abstract contract
OtherContract oc = OtherContract(_destination);
oc.otherMethod(address(this), _count * unitPrice);
}
}
Если вы знаете метод вызова, вы можете использовать абстрактный контракт
contract OtherContract {
function otherMethod(address _to, uint _price);
}
contract MyContract {
uint public unitPrice = 100;
function myMethod(address _destination, uint _count) {
// _destination is a contract that implements OtherContract
OtherContract oc = OtherContract(_destination);
// call method from other contract
oc.otherMethod(address(this), _count * unitPrice);
}
}
ЭфирПол
Исмаэль
ЭфирПол
Исмаэль