Estoy escribiendo mi propio contrato inteligente y quiero llamar a una función de un contrato que ya se implementó. El fragmento de mi código:
function myFunc(address _contractAddress, address _user, uint _price) onlyOwner {
//... some code ...
require(_contractAddress.call(bytes4(sha3("func(address, uint256)")), _user, _price));
//... some code ...
}
Estoy usando Remix IDE. Me muestra esta advertencia:
uso de "llamada": el uso de "llamada" de bajo nivel debe evitarse siempre que sea posible. Puede dar lugar a un comportamiento inesperado si el valor devuelto no se gestiona correctamente. Utilice llamadas directas especificando la interfaz del contrato llamado.
¿Cómo debo solucionar este problema? Delegatecall produce una advertencia similar. ¿Tal vez hay otras formas de llamar a la función de otro contrato?
En las versiones más nuevas de solidity, puede usar contratos abstractos o interfaces .
abstract
palabra clave para compilar correctamente y el virtual
modificador en funciones.Estoy bastante seguro de que las interfaces están representadas en un nivel bajo por contratos abstractos con todas las funciones virtuales externas y sin campos de datos internos.
MiContrato.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);
}
}
Si conoce el método para llamar, puede usar un contrato abstracto
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);
}
}
EtherPaul
ismael
EtherPaul
ismael