0

I have written a contract as follows:

pragma solidity ^0.4.0;

/*
Simple contract that mediates disputes using a trusted arbiter
*/
contract Taxi {

    enum State {IDLE, FINDING_DRIVER, AWAITING_PAYMENT, AWAITING_DESTINATION, COMPLETE}
    State public currentState;
    mapping (address => uint) public balances;
    bytes32 STRING_COMPLETE = "Complete";
    bytes32 STRING_PARTIAL = "Partial";

    modifier customerOnly() { require(msg.sender == customer); _; }
    modifier driverOnly() { require(msg.sender == driver); _; }
    modifier arbiterOnly() { require(msg.sender == arbiter); _; }
    modifier inState(State expectedState) { require(currentState == expectedState); _; }

    address public customer;
    address public driver;
    address public arbiter;

    function Taxi(address _customer, address _driver, address _arbiter) public {
        customer = _customer;
        driver = _driver;
        arbiter = _arbiter;
    }

    function assignDriver() customerOnly inState(State.IDLE) public {
        //arbiter.transfer(this.balance);
        currentState = State.FINDING_DRIVER;
    }

    function confirmAmount(uint amount) driverOnly inState(State.FINDING_DRIVER) public returns (bool ) {
        if(amount < 0) {
            amount = 20;
        }
        //driver has set this amount and user has accepted this fare, return true if customer has sufficient balance
        if(balances[customer] < amount) {
            return false;
        }
        currentState = State.AWAITING_DESTINATION;
        balances[arbiter] += amount;
        balances[customer] -= amount;
        return true;
    }
}

First I execute the assignDriver function which runs correctly. Later, when I execute the confirmAmount function, I get the error:

transact to Taxi.confirmAmount 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.

I tried to add the payable keyword to the constructor, but still I got the same error. What can be the problem?

  • I would assume one of your modifiers is reverting the transaction. Try removing the modifiers to confirm and then add them back in one at a time to see which one. – smarx Apr 4 '18 at 0:20
  • I'm guessing this is false. modifier customerOnly() { require(msg.sender == customer); _; } – Rob Hitchens - B9lab Apr 4 '18 at 0:43
  • Maybe you should describe what do you want to do to be able to help – Jaime Apr 4 '18 at 1:09
  • @RobHitchens is correct. The confirmAmount could be called by driver only. modifier driverOnly() { require(msg.sender == driver); _; } was false in my case. – Rohan Apr 4 '18 at 1:52
0

It is unclear what the comfirmAmount does:

function confirmAmount(uint amount) driverOnly inState(State.FINDING_DRIVER) public returns (bool ) {
        if(amount < 0) {
            amount = 20;
        }

This will never enter the if as numbers below zero are not possible in solidity.

//driver has set this amount and user has accepted this fare, return true if customer has sufficient balance
if(balances[customer] < amount) {
    return false;
}
currentState = State.AWAITING_DESTINATION;
balances[arbiter] += amount;
    balances[customer] -= amount;
    return true;
}

The balances are never changed for custumer, there is no function that does that since the beginning so this should always return false.

But none of the issues above will revert. The only possibility is that the transaction to execute confirmAmount is not done by the account "driver" and the modifier throws.

  • Yes the amount won't be negative because of the unsigned integer. confirmAmount should have been called by the "driver", which I wasn't calling as a driver. Thanks for pointing that out. – Rohan Apr 4 '18 at 1:55

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.