0

I have two contracts. When I run a function in contract CourierService that transfers the balance of a deployed contract POD to an ethereum address named arbitrator. It does not work. I get an error. What are the possible reasons for it to fail? The POD contract named mainContract has 12 ether when I run the transferEther function from CourierService

contract POD{
address public seller;
address public buyer;
address public nextCourier;

.. }

contract CourierService{
address public mainContract;//the first original contract
address public parentContract;

 function transferEther(contractState st) OnlyDestinationAddress{
    require(st == contractState.Dispute);//require the child's state is Dispute
    arbitrator.transfer(this.balance);
   if(parentContract == mainContract)
   {
       pod = POD(mainContract);
       pod.setState(POD.contractState.DisputeVerificationFailure);
       arbitrator.transfer(mainContract.balance);//ERROR

   }else{
       .....

   }
}

}

  • You'll certainly need to share your code for someone to help. You typically don't need to use this at all to call a function within the same contract. (It can be used to force "external" calling conventions, but that's an extreme exception.) – smarx Apr 26 '18 at 15:07
  • @smarx I am using this to get the balance – Haya Raed Apr 26 '18 at 15:11
  • @HayaRaed Are you using contract A to call a function in contract B? – viz Apr 26 '18 at 15:18
  • this.balance gives you the amount of ether in the current contract. In other words, this.balance is the balance of whatever contract transferEther is in. You haven't shared the full code, so I have no idea what mainContract is (perhaps the same contract?). This isn't enough information to tell you what is happening. – smarx Apr 26 '18 at 15:19
  • @viz I call a function from another contract after creating the instance pod , which is after calling 'this' – Haya Raed Apr 26 '18 at 15:24
1

A contract can't forcibly transfer ether from another contract. recipient.transfer(amount) transfers amount of ether from the contract to the recipient.

So what's happening is that this line:

arbitrator.transfer(this.balance);

is sending all the ether owned by the contract to arbitrator. Then this line:

arbitrator.transfer(mainContract.balance);

tries to transfer more ether. Specifically, it tries to transfer the amount of ether held by mainContract. If that's more than 0, the call will fail because the contract has an insufficient balance.

If you want mainContract to send ether, you'll have to write code in mainContract to do that, something like:

function transferBalanceTo(address recipient) public {
    require(msg.sender == whoeverIsAllowedToDoThis); // be sure to do some auth

    recipient.transfer(address(this).balance);
}

Then you can call it from the other contract:

mainContract.transferBalanceTo(arbitrator);
  • Can i do a modifier to allow calls from the courierService contract only? or modifiers can only be used with ethereum addresses of entities not contracts? – Haya Raed Apr 28 '18 at 7:47
  • Modifiers can do anything any other code can do. – smarx Apr 28 '18 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.