¿Cómo puede llamar a una función pagadera en otro contrato con argumentos y enviar fondos?

Tengo un contrato llamado Call:

contract Call {
  ...
  function () payable {
    // TODO: Call the call function in the main contract
    // and forward all funds (msg.value) sent to this contract
    // and passing in the following data: msg.sender
  }
}

Aquí está el Maincontrato:

contract Main {
  ...
  function call(address senderAddress) public {
    // Make the code in here run when someone sends ethers to the Call contract
  }
}

Entonces, quiero tenerlo para que cada vez que alguien envíe el Callcontrato a ethers, envíe todos los ethers al Maincontrato mientras ejecuta la callfunción en el Maincontrato con los argumentos necesarios.

Se puede hacer esto?

Respuestas (2)

Actualización por comentario de @Girish, en Solidity 0.6+ la sintaxis ha cambiado a:address.function{value:msg.value}(arg1, arg2, arg3)


Original

La sintaxis general para llamar a una función en otro contrato con argumentos y enviar fondos es:address.func.value(amount)(arg1, arg2, arg3)

funcnecesita tener el payablemodificador (para Solidity 0.4+).

Completando la respuesta de @Edmund con estos detalles importantes, aquí hay un ejemplo que compila:

pragma solidity ^0.4.0;

contract PayMain {
  Main main;
  function PayMain(address _m) {
     main = Main(_m);
  }
  function () payable {
    // Call the handlePayment function in the main contract
    // and forward all funds (msg.value) sent to this contract
    // and passing in the following data: msg.sender
    main.handlePayment.value(msg.value)(msg.sender);
  }
}

contract Main {
  function handlePayment(address senderAddress) payable public {
      // senderAddress in this example could be removed since msg.sender can be used directly
  }
}

Destacando también lo que escribió:

Tenga en cuenta que esto solo funcionará si las personas que envían los fondos envían suficiente gasolina para cubrir la llamada a Main y lo que sea que haga en ella.

acerca de su comentario sobre msg.sender, el valor de msg.senderserá la dirección dePayMin
A partir de Solidity 0.6.0, address.function.value(amount)(arg1, arg2, arg3) está en desuso. Utilice address.function{value:msg.value}(arg1, arg2, arg3) en su lugar.
@GirishThimmegowda Gracias, lo agregué al principio de la respuesta. (No hay tiempo en este momento para probar y actualizar la respuesta completa).

Si, esto se puede hacer. Sin embargo, no digas call"llamar", es buscar problemas.

Necesitará el contrato que recibe el pago para conocer la dirección de su contrato principal. Imaginando que está almacenado en una variable llamada main_addr, y Main tiene un método llamado handlePayment(), puedes llamarlo con algo como:

Main m = Main(main_addr);
m.handlePayment();

Esto también puede tomar parámetros, por ejemplo, es posible que desee decirle lo que obtuvo msg.sendery msg.value.

Tenga en cuenta que esto solo funcionará si las personas que envían los fondos envían suficiente gasolina para cubrir la llamada a Main y lo que sea que haga en ella. En algunas situaciones, puede ser mejor simplemente registrar un evento en el contrato pagadero y manejarlo más tarde.

¿Podría ser más específico sobre cómo esta forma de llamar puede tomar otros parámetros?
Ver la respuesta de @eth.
no responde la pregunta