1

On using,

  1. require(msg.value == registerFeeMap[msg.sender] /_currentRate) (fractional ETH value calculated)
  2. require(msg.value == registerFeeMap[msg.sender]*10**18/ _currentRate)
    (ETH converted to Wei)
  3. require((msg.value*10**18) == registerFeeMap[msg.sender]*10**18/ _currentRate)

in, function feePayment(string _sign, uint _currentRate) external payable on using all 3 I get, VM Exception while processing transaction: revert

  1. _currentRate is parameter for function feePayment(string _sign, uint _currentRate) external payable here, _sign is the MetaMask signed message string and _currentRate is INR vs ETH value from CryptoCompare API.

  2. registerFeeMap is initialised in function newHome(string _add, string _type, uint _startEpoch, uint _endEpoch, uint _months, uint _rent, uint _security) external with values depending on _rent variable.

Example value stored in registerFeeMap >= 100
Example value of _currentRate from API = 8380

How should I convert Eth to Wei for require(), if fractional value of Ether is to be used for payments ?

My Contract Code is as follows

pragma solidity ^0.4.19;

contract Owned {

address owner;

function Owned() public {
    owner = msg.sender;
}

modifier onlyOwner() {
    require(msg.sender == owner);
    _;
}
}


contract Rent is Owned {    
struct Person {

    address eth;
    string legalName;
    string email;
    uint aadhaar;

    string signTerms; //sign on the Terms and Conditions

    uint[] myOwned;
    uint[] myRented;
}

struct Parties {

    address landlord;
    address tenant;

    string signLandlord;
    string signTenant;

    bool completed;
}


struct House {

    string addressHouse;
    string type_of_property;

    uint startEpoch;
    uint endEpoch; 

    uint monthDuration; // difference in Months of these Dates

    uint rentAmount;
    uint securityFee;
    uint registerFee;

    bool completed;
}

struct OtherDetails {

    string latitude;
    string longitude;

    string ipfs_url; // for Future Versions of, when we support IPFS URLs

    uint squareFootage;
    uint numberBedrooms;
    string others;

    bool completed;
}

struct Checks {

    bool isValid;

    bool tenantApprove;
    bool govApprove;

    bool tenantCheck;

    bool paidRegisterFee;
    bool paidSecurityFee;
}

Parties[] public allParties; 
House[] public allHouses;
OtherDetails[] public allOtherDetails;
Checks[] private allChecks;

mapping(address => Person) public addressToPerson;
mapping(address => bool) private checkUser;
mapping(uint => bool) private checkAadhaar;

mapping(address => uint) private registerFeeMap;
mapping(address => uint) private securityFeeMap;


function Rent() public {

    checkUser[owner] = true;
    var govt = Person(owner, 'Owner', 'Owner', 0, 'No Sign', new uint[](0), new uint[](0));

    addressToPerson[owner] = govt;
}


event registerParty(string message);

function registerParties(address _tenant) external  {

    require(msg.sender != _tenant);

    if(checkUser[msg.sender] == true)
    {
        if(checkUser[_tenant] == true)
        {
            var newParty = Parties(msg.sender, _tenant,'N/A', 'N/A', true);
            var index = allParties.push(newParty) - 1;

            var newHouse = House('No Address Added', 'No Property Type', 0, 0, 0, 0, 0, 0, false);
            allHouses.push(newHouse);

            var newDetails = OtherDetails('28.7041', '77.1025', 'Currently IPFS Not Supported', 0, 0, 'N/A', false);
            allOtherDetails.push(newDetails);

            var newChecks = Checks(false, false, false, false, false, false);
            allChecks.push(newChecks);

            var user = addressToPerson[msg.sender];
            user.myOwned.push(index);

            var tenant = addressToPerson[_tenant];
            tenant.myRented.push(index);

            registerParty('Tenant was Successfully added to Contract, Proceed to Step 2');
        }

        else
        {
            registerParty('Tenant is not registered on Charter, registration of both parties is required');
        }
    }

    else
    {
        registerParty('Kindly register on Charter, before drafting a Contract');
    }
}


event registerHome(string message, uint FeePayable);

function newHome(string _add, string _type, uint _startEpoch, uint _endEpoch, uint _months, uint _rent, uint _security) external {

    if(checkUser[msg.sender] == true)
    {
        var user = addressToPerson[msg.sender];

        uint num = user.myOwned.length - 1;

        if(num < 0)
        {
            registerHome('Kindly fill Tenant Info in Step 1 before proceeding to Step 2', 0);
        }

        else
        {
            uint index = user.myOwned[num];
            var houseOwner = allParties[index];

            if(houseOwner.landlord != msg.sender)
            {
                registerHome('Kindly register on Charter, before drafting a Contract', 0);
            }

            else
            {
                var home = allHouses[index];

                if(home.completed == false)
                {
                    home.addressHouse = _add;
                    home.type_of_property = _type;

                    home.startEpoch = _startEpoch;
                    home.endEpoch = _endEpoch;

                    home.monthDuration = _months;

                    home.rentAmount = _rent;
                    home.securityFee = _security;

                    var _tenant = allParties[index].tenant; 

                    if((home.monthDuration < 12)&&(home.monthDuration > 0))
                    {
                        home.registerFee = 100;
                        home.completed = true;

                        registerHome("Property's Information successfully entered, Proceed to Step-3", home.registerFee);
                    }

                    else if(home.monthDuration <= 60)
                    {
                        if(_security > 0)
                        home.registerFee = 100 + ((2 * 12 * _rent) / 100) + 1100;

                        else
                        home.registerFee = ((2 * 12 * _rent) / 100) + 1100;

                        home.completed = true;

                        registerHome("Property's Information successfully entered, Proceed to Step-3", home.registerFee);
                    }

                    else if(home.monthDuration <= 120)
                    {
                        if(_security > 0)
                        home.registerFee = 100 + ((3 * 12 * _rent) / 100) + 1100;

                        else
                        home.registerFee = ((3 * 12 * _rent) / 100) + 1100;     

                        home.completed = true;

                        registerHome("Property's Information successfully entered, Proceed to Step-3", home.registerFee);       
                    }

                    else if(home.monthDuration <= 240)
                    {
                        if(_security > 0)
                        home.registerFee = 100 + ((6 * 12 * _rent) / 100) + 1100;

                        else
                        home.registerFee = ((6 * 12 * _rent) / 100) + 1100;

                        home.completed = true;
                        registerHome("Property's Information successfully entered, Proceed to Step-3", home.registerFee);
                    }

                    else
                    {
                        home.completed = false;
                        registerHome('Kindly Enter Duration of Contract Correctly.. (Min - 1 month, Max - 240 Months' , 0);
                    }
                }

                else
                {
                    registerHome('Home Registration is already Completed ', 0);
                }

                registerFeeMap[msg.sender] = home.registerFee;
                securityFeeMap[_tenant] = home.securityFee;
            }

        }
    }

    else
    {
        registerHome('Kindly register on Charter, before drafting a Contract', 0);
    }
}



event feePay(string message);

function feePayment(string _sign, uint _currentRate) external payable {

    require(msg.value == (registerFeeMap[msg.sender] * 10**18 / _currentRate));

    if(checkUser[msg.sender] == true)
    {
        var user = addressToPerson[msg.sender];

        uint num = user.myOwned.length - 1;

        if(num < 0)
        {
            feePay('Complete all the Steps, before paying Registration Fee Payment');
        }

        else
        {

            uint index = user.myOwned[num];
            var party = allParties[index];
            var house = allHouses[index];
            var details = allOtherDetails[index];
            var checks = allChecks[index];

            if((details.completed == true)&&(house.completed == true)&&(party.completed == true))
            {
                user = addressToPerson[msg.sender];
                checks.paidRegisterFee = true;
                party.signLandlord = _sign;

                feePay('Government Registration Fee Payment Successful, Tenant Verification pending..');
            }

            else 
            {
                feePay('Complete all the Steps given above before Fee Payment');
            }
        }
    }

    else
    {
        feePay('Kindly register on Charter, before drafting a Contract');
    }
}
}
  • It is impossible to know without seeing the values. One problem I see right off the bat is that you use 10^18 rather than 10**18. Try that. – shane Feb 8 at 17:43
  • 5
    Here is a simple conclusion from your description: msg.value != registerFeeMap[msg.sender] * 10^18 / _currentRate. Other than that, it is not clear what you are asking, not what you are trying to achieve. If you're hoping to get help here, then you should consider explaining yourself properly (including all the code necessary to reproduce whatever problem it is that you're struggling with). – goodvibration Feb 8 at 17:48
  • I am calculating payments in INR (this value is stored in registerFeeMap mapping, eg 100), the function parameter _currentRate holds value of INR vs Eth conversion rate (eg 8,380 INR for 1 ether), the division of registerFeeMap[msg.sender] / _currentRate can yield a decimal value (100 / 8380), how to handle payments when value of ETH calculated is in fractions. – anudishjain Feb 8 at 17:54
  • require(msg.value == registerFeeMap[msg.sender] * 10**18 / _currentRate) gives the same error. VM Exception while processing transaction: revert – anudishjain Feb 8 at 18:11
  • Please elaborate on how you have initialized registerFeeMap[msg.sender] and _currentRate, and what value you are passing when you call the function. – goodvibration Feb 8 at 19:39
1

Example value stored in registerFeeMap - 100
Example value of _currentRate from API - 8380

In uint math

100/8380 = 0

identically (i.e. always).

So if your msg.value is different from zero, your first require argument is not true and reverts.

The second one is wrong, ‘^’ operator for elevation is a mistake.

The third one should be:

 (A * 10**18 / B) / 10**18

or you can multiply msg.value * 10**18 before to compare to it.

This as general discussion about division in Solidity.

But are you sure to be tuned on msg.value properties?

Msg.value is expressed in wei.

Are you worried about 0.01193317422 wei?

I don’t think so. Read your data and print them to console. You will be more confident after that.

(1 wei = 1 ether / 10**18, I.e. 0.000000000000000001 ether)

  • tried require((msg.value*10**18) == registerFeeMap[msg.sender]*10**18/ _currentRate) got same error, how to make require take fractional value of Ether as 100 / 8380 = 0.01193317422 – anudishjain Feb 9 at 8:00
  • Msg.value is expressed in wei. Are you worried about 0.01193317422 wei? I don’t think so. Read your data and print them to console. You will be more confident after that. (1 wei = 1 ether / 10**18, I.e. 0.000000000000000001 ether) – Rick Park Feb 9 at 8:51

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.