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);
}
}'''