[Ethereum] How to you call a payable function in another contract with arguments and send funds

contract-designcontract-developmentcontract-invocationsolidity

I have a contract named 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
  }
}

Here is the Main contract:

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

So, I want to have it so that whenever someone sends ethers the Call contract, it forwards all the ethers to the Main contract while running the call function in the Main contract with the necessary arguments.

Can this be done?

Best Answer

Update per @Girish comment, in Solidity 0.6+ the syntax has changed to: address.function{value:msg.value}(arg1, arg2, arg3)


Original

The general syntax for calling a function in another contract with arguments and sending funds is: address.func.value(amount)(arg1, arg2, arg3)

func needs to have the payable modifier (for Solidity 0.4+).

Completing @Edmund's answer with these important details, here's an example that compiles:

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
  }
}

Also emphasizing what he wrote:

Be aware that this will only work if the people sending the funds send enough gas to cover the call to Main and whatever you do in it.

Related Topic