0

I have a function makePayment in one Contract:

function payLoan(Loan _loanAddress) payable onlyOwner public {

// Outgoing payment
Loan myLoan = Loan(_loanAddress);
uint256 payment = msg.value;

// Make payment if sufficient funds, otherwise only pay what is available
if (funds >= payment){

    // Make payment
    myLoan.makePayment.value(payment);
    funds -= payment;
}else{

    // Partial payment
    myLoan.makePayment.value(funds);
    funds = 0;
}

and I want to make a payment into another contract with the function makePayment:

    function makePayment() onlyOwner payable public {

        received = msg.value;
        if (received >= balance){
            received    -= balance;
            amtPaid     += balance;
            balance     = 0;
        } else {
            balance     -= received;
            amtPaid     += received;
            received    = 0;
        }

    }

It seems to work and the funds are received by the first contract, but the amount sent is never received. None of the variables are changed as a result of the call. Any idea what is wrong? Thanks.

Here is a further simplification and revised attempt. I still get the error "transact to Borrower.payLoan errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The constructor should be payable if you send value. Debug the transaction to get more information."

    pragma solidity ^0.4.18;

contract Borrower {
    uint256 public amountReceived;

    function Borrower() payable public {
    }

    function payLoan(Loan _loan) payable public {

        // Outgoing payment
        Loan loan = Loan(_loan);
        amountReceived = msg.value;

        // Make payment
        loan.payLoan.value(amountReceived)();
    }   

    function getThisBalance() public view returns (uint256){

        return this.balance;
    }
} // Borrower

contract Loan {
    address public borrower;
    uint256 public loanBalance;

    function payLoan() payable public {
        uint256 received = msg.value;
        loanBalance -= received;
        }

    function Loan(address _borrower) payable public {
        borrower    = _borrower;
        loanBalance = msg.value;
        }

    function getThisBalance() public view returns (uint256){

        return this.balance;
    }
} // Loan
2
  • I have just tried your last revision in remix and I do not get exception on step 6. I don't quite follow the logic of your contract. You have two payable functions in Loan. And one of them adds paid value to the balance, and another subtracts it.
    – abb
    Jan 28, 2018 at 23:47
  • For debugging you could also add "function getThisBalance() public view returns (uint256) { return this.balance; }" function to Loan contract, to see balance of contract account from the point of view of the blockchain. This function returns actual ether owned by the contract, not balance value you "manually" track by your own code.
    – abb
    Jan 29, 2018 at 0:04

2 Answers 2

3

I think you're missing parentheses to actually call the function:

myLoan.makePayment.value(payment)();

and

myLoan.makePayment.value(funds)();
10
  • Thanks. I tried to do so, but could not get it work. I tried a different tack (see edited question above). Any idea why it does not actually transfer the ether? Jan 28, 2018 at 12:03
  • Can you share how you're calling these functions? Are you using a tool like Remix or MEW? Or are you writing JavaScript or Python or Java to call them? (If so, please share that code.)
    – user19510
    Jan 28, 2018 at 12:09
  • directly in Remix using Javascript VM Jan 28, 2018 at 12:25
  • Are you remembering to send ether by changing the "value" in the upper right?
    – user19510
    Jan 28, 2018 at 12:48
  • Yes! I tried it several times! Jan 28, 2018 at 13:51
0

So I have figured it out. The problem was that when I was running payLoan I entered the borrower address into the box to the left of create circled in red instead of the box circled in yellow to the right of the function payLoan. I did not notice that I could click there and enter the address.

Running payLoan

Now that I can get the function to fire properly, I cleaned up the code as well. I also realized that I did not need to fund Borrower as any payments were coming from msg.sender anyway. I also made the loanBalance itself a counter not holding ether but rather tracking the payments actually made. Now when I send ether, loanBalance goes down by the amount of ether received and Loan has a balance corresponding to the amount of ether received. Simple program but very educational! Here is the code:

pragma solidity ^0.4.18;

contract Borrower {
    string  public borrowerName;
    uint256 public amountToPay;

    function payLoan(Loan _loan) payable public {

        // Outgoing payment
        Loan loan   = Loan(_loan);
        amountToPay = msg.value;

        // Make payment
        loan.makePayment.value(amountToPay)();
    }   

    function getThisBalance() public view returns (uint256){

        return this.balance;
    }
} // Borrower

contract Loan {

        address public borrower;
        uint256 public loanBalance;

        uint256 public received;

        function Loan(address _borrower, uint _loanBalance) public {
            borrower    = _borrower;
            loanBalance = _loanBalance;
            }

        function makePayment() payable public {

            received    =  msg.value;
            loanBalance -= received;
        }

    function getThisBalance() public view returns (uint256){

        return this.balance;
    }
} // Loan

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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