¿Cómo llamar a una función desde un contrato ya implementado?

Traté de usar la función "Llamar", como se describe aquí: Función de llamada desde el contrato implementado

Pero parece que no está funcionando en absoluto.

¿Cómo puedo llamar a una función desde un contrato inteligente implementado existente?

Estoy tratando de llamar a una función simple desde una dirección existente que recibe una dirección como parámetro.

Este es el código que estoy usando para llamar a la función externa:

Contrato A:

function CallExternalFunction(address externalContractAddress) 
{    
    externalContractAddress.call(bytes4(sha3("FunctionX(address)")),0xfffff);
    //sends 0xfffff as input parameter to the external contract
}

El código fuente del contrato ya desplegado es así:

Contrato B:

contract test { 

mapping (address => uint256) public balanceOf; 

function test() { 

}

function FunctionX(address _address)
{
    balanceOf[_address] = 50000;    
}
}
¿Tiene el código fuente o ABI del contrato para llamar?
Actualicé la pregunta con el código fuente.
No parece haber nada malo con este enfoque; es solo una llamada de nivel inferior al contrato externo. Solo hay algunas advertencias. Con calltoda su gasolina (menos ~30k) se reenviará al contrato externo para que haga con ella lo que le plazca, lo cual es una vulnerabilidad, especialmente si la llamada falla y se establece de manera predeterminada en la función de respaldo. calltambién rompe la seguridad de tipo para los argumentos de la función y seguirá transfiriendo ether si se emite una excepción en la ejecución, así que asegúrese de colocar la llamada en a require()para revertir las transacciones que no se comportan como se esperaba.

Respuestas (1)

Prueba esto. Implemente la persona que llama e implementará el contrato de prueba para simplificar las cosas.

contract Caller {

  test public t;

  function Caller() {
    t = new test();
  }

  function callIt(address theAddress)
    public
    returns(bool success)
  {
    t = test(t); <===== here the other contract address can be called t = test([OtherContractAddress]); example: test(0x12345);
    bool result = t.FunctionX(theAddress);
    return result;
  }
}

contract test { 

  mapping (address => uint256) public balanceOf; 

  function FunctionX(address _address) public returns(bool success)
  {
    balanceOf[_address] = 50000; 
    return true;
  }
}

En Remix para mostrarlo funcionando.

ingrese la descripción de la imagen aquí

Puede usar una estructura similar para un contrato que ya existe si tiene el código fuente, usando un contrato de interfaz. Aquí el compilador "Caller" puede ver lo suficiente de la prueba {} para administrar la interfaz.

contract Caller {

  test public t;

  // where test is deployed and the address is known
  // Pass in the address for test {}.

  function Caller(address tAddress) {
    t = test(tAddress); // address of contract t
  }

  function callIt(address theAddress)
    public
    returns(uint bal)
  {
      return t.FunctionX(theAddress);
  }
}

// This interface constant includes the function interfaces (exactly as in the "real" contract" with the fynctions undefined
// This tells the compiler how to communicate with the ABI in test{}.

contract test { 
  function FunctionX(address _address) public returns(uint balanceOf) {}
}
El ejemplo que mostró parece ser los 2 contratos en la misma dirección implementada, ¿verdad? En mi caso, el Contrato A y B están desplegados en diferentes direcciones (actualicé la descripción con el contrato A y B). ¿Sabe cómo hacerlo funcionar cuando los contratos se implementan en diferentes direcciones?
No. No es posible tener dos contratos en una dirección. Dos contratos en un solo archivo fuente, con el primer contrato implementando una instancia del otro (una forma de conocer la dirección del otro). Llamante en 0xb872, prueba en 0x22e6. t = new test();despliega una nueva instancia de prueba. Para la prueba ya implementada{}, puede pasar la dirección o codificar la dirección. La persona que llama deberá saberlo para realizar la llamada. El archivo fuente único le da al compilador una vista del contrato de prueba para que entienda la interfaz de prueba{} y tenga el código de bytes que necesita para implementar una nueva prueba{}.
Me gusta la idea de la declaración hacia adelante. Tenga en cuenta que el compilador (solcjs) genera una advertencia de "Variable local no utilizada" para _address en el ejemplo anterior.