0

I am new to Solidity and can't understand why I am getting the above error even though the function purchaseProduct() is declared as payable. I tried this code on Remix IDE and got this error.
VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
Everything is working fine except for the purchaseProduct() function. I am trying to fetch the data from struct 'User', 'Product' and strore the data in a new struct that is 'Order'.
I have carried out validation using require(). While running the code on Remix:
1. Create 2 users
2. Create Product using first user and then,
3. purchaseProduct using second user

pragma solidity >=0.5.0;
pragma experimental ABIEncoderV2;

//Address: '0x7772B9117586b5F745bDb563a935E91b00449157'

contract Buyproduct{

    uint public orderCount = 0;
    mapping(uint => Order) public orders;

    uint public productCount = 0;
    mapping(uint => Product) public products;

    uint public userCount = 0;
    mapping(address => User) public users;

    struct Order {
        uint oid;
        address payable seller;
        address payable buyer;
      //  string timestamp;
        string status;
        uint pid;
        string location;
        uint quantitiy;
    }

    struct Product {
        uint pid;
        string name;
        uint price;
        address payable seller;

        string info;
        uint quantity;
    }

    struct User {
        uint uid;
        string name;
        uint role;
        address payable user;
        string location;
        bool created;
    }

    event ProductCreated(
        uint pid,
        string name,
        uint price,
        address payable seller,
        string info,
        uint quantity
    );

    event  UserCreated(
        uint uid,
        string name,
        uint role,
        address payable user,
        string location,
        bool created
    );

    event ProductPurchased(
        uint oid,
        address payable seller,
        address payable buyer,
        string status,
        uint pid,
        string location,
        uint quantity
    );

    event ReviewAdded(
        uint rid,
        address reviewer,
        uint pid,
        string review
    );

    function createUser(string memory _name, uint _role, string memory _location) public payable{
        //No repeated address
        require(users[msg.sender].created == false, 'User already created');
        //Increase userCount
        userCount++;
        //Add user
        users[msg.sender] = User(userCount, _name, _role, msg.sender, _location, true);
        //Trigger an event
        emit UserCreated(userCount, _name, _role, msg.sender, _location, true);
    }

    function createProduct(string memory _name, uint _price, string memory _info, uint _quantity) public payable {
        // Require a valid price
        require(_price > 0, 'Invalid Price');
        // Increment product count
        productCount ++;
        // Create the product
        products[productCount] = Product(productCount, _name, _price, msg.sender, _info, _quantity);
        // Trigger an event
        emit ProductCreated(productCount, _name, _price, msg.sender, _info, _quantity);
    }

    function purchaseProduct(uint _id, /*string memory timestamp,*/ uint _quantity) public payable {
        // Fetch the product
        Product memory _product = products[_id];
        // Fetch the owner
        address payable _seller = _product.seller;
        //Validate the buyer
        require(users[msg.sender].created == true, 'Unregistered user');
        // Make sure the product has a valid id
        require(_product.pid > 0 && _product.pid <= productCount, 'Invalid Product ID');
        // Require that there is enough Ether in the transaction
        require(msg.value >= _product.price, 'Not enough ether in Wallet');
        // Require that the buyer is not the seller
        require(_seller != msg.sender,'Invalid Purchase');
        //Incrmement orderCount
        orderCount++;
        // Transfer ownership to the buyer
        orders[orderCount] = Order(orderCount, _seller, msg.sender,/* ts,*/ 'Ordered', _product.pid, users[msg.sender].location, _quantity);
        //Reduce the quantity of the product
        _product.quantity -= _quantity;
        // Pay the contract by sending them Ether
        address payable wallet = address(uint160(address(this)));
        wallet.transfer(msg.value);
        // Trigger an event
        emit ProductPurchased(orderCount, _seller, msg.sender, /*timestamp,*/ 'Ordered', _product.pid, users[msg.sender].location, _quantity);
    }


}'''
  • The error comes when calling the function purchaseProduct() in remix – Spinescream Apr 8 at 11:06
  • Sorry, What is the error you are getting while calling purchaseProduct(), Please post the error message too. – GraphicalDot Apr 8 at 11:16
  • I have edited and added the error message in bold. The bold part is the output I am getting in console. – Spinescream Apr 8 at 11:21
1
    function createProduct(string memory _name, uint _price, string memory _info, uint _quantity) public payable {

This function signature has _price in ethers. So try changing the default units to the ether from Wei and send the appropriate price of the product. enter image description here

Mine is working

[vm]from:0x4b0...4d2dbto:Buyproduct.purchaseProduct(uint256,uint256) 0x1df...bda71value:2000000000000000000 weidata:0xa04...00001logs:1hash:0x4e0...0d2b0

You also don't need to call these explicitly.

address payable wallet = address(uint160(address(this)));
wallet.transfer(msg.value);

Contract balance will be updated automatically. You can check by implementing this function on your contract.

    function getBalance()
             public 
             view 
             returns(uint) {
                return address(this).balance;}

| improve this answer | |
  • Still getting the error – Spinescream Apr 8 at 11:58
  • What was your product value? and whats the value you are sending from your registered user? – GraphicalDot Apr 8 at 11:59
  • The values I am passing for the function are _id=1 and _quantity=1 alongwith value=3 eth – Spinescream Apr 8 at 12:17

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.