0

I am playing around with smart contracts and decided to build a simple contract for an eCommerce store. The contract allows the owner to add items to the contract with price in USD, it allows the owner to remove a specific item and view current items. Furthermore, It also allows buyers to buy the items from the contract using buy() function. The issue here is that when I call the buy() function the transaction reverts every time on Remix's EVM, I don't really know what's going on here. I would love your input.

Here's my code.

PriceConverter.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

library PriceConverter{

    
    function getPrice(AggregatorV3Interface priceFeed) internal view returns (uint256) {
      
        (, int256 answer, , , ) = priceFeed.latestRoundData();
        
        return uint256(answer * 1e10);
    }


    function getConversionRate(uint256 ethAmount,
        AggregatorV3Interface priceFeed)
        public
        view
        returns (uint256)
    {
        uint256 ethPrice = getPrice(priceFeed);
        uint256 ethAmountInUsd = (ethPrice * ethAmount)/1e18;
        return ethAmountInUsd;
    }

}

Here's the code for Buying.sol my main deployment contract if you will.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "contracts/PriceConverter.sol";


contract Buying {
    using PriceConverter for uint256;

    address[] private s_sendersAddress;
    address private immutable i_owner1 = msg.sender;
    AggregatorV3Interface public priceFeed;
    uint256 private walletAmmount;

    modifier OwnershipAccess{

        require(msg.sender == i_owner1, "Only the Owner of this contract can perform this action");
        _;
    }


    struct ItemList {
        string item;
        uint256 price;
    }
    
    ItemList[] internal s_itemList;
    
    mapping(bytes32 => uint256) private s_itemsToIndex;
    mapping(address => uint256) private s_peopleWhoBought;
    

    function addItemToList1(

        string memory _itemName, 
        uint256 _itemPrice) public OwnershipAccess {

        bytes32 itemKey = keccak256(bytes(_itemName));
        
        require(itemKey.length > 0, "Please enter the Item's name.");
        require(_itemPrice > 0, "Please enter a Valid AMount");
        
        ItemList memory newItem;
        newItem.item = _itemName;
        newItem.price = _itemPrice * 10 ** 18;
        s_itemList.push(newItem);

        s_itemsToIndex[itemKey] = s_itemList.length;
    }

    function getItemsFromList() public OwnershipAccess view returns 
    (
        string[] memory, 
        uint256[] memory
        ){

        uint256 length = s_itemList.length;
        string[] memory itemNames = new string[](length);
        uint256[] memory itemPrices = new uint256[](length);

        for (uint256 i=0; i<length; i++){
            itemNames[i] = s_itemList[i].item;
            itemPrices[i] = (s_itemList[i].price)/10 ** 18;
        }

        return (itemNames, itemPrices);
}

    function removeAnItem(string memory _itemName) public OwnershipAccess{

        bytes32 itemKey = keccak256(bytes(_itemName));
        uint256 itemIndex = s_itemsToIndex[itemKey];
        require(itemIndex > 0, "Please Enter a valid item name");

        uint256 lastIndex = s_itemList.length - 1;
        ItemList memory lastItem = s_itemList[lastIndex];
        s_itemList[lastIndex - 1] = lastItem;

        bytes32 lastItemKey = keccak256(bytes(s_itemList[lastIndex].item));
        s_itemsToIndex[lastItemKey] = itemIndex;

        s_itemList.pop();

        delete s_itemsToIndex[itemKey];
        
    }


    function buy(string memory _itemName) public payable {

        bytes32 itemKey = keccak256(bytes(_itemName));

        require(itemKey.length > 0, "Please enter the item's name.");
        require(msg.value > 0, "Please send a valid amount of ETH.");

        uint256 itemIndex = s_itemsToIndex[itemKey];
        require(itemIndex > 0, "Item does not exist.");

        ItemList storage item = s_itemList[itemIndex - 1];
        uint256 itemPriceInUSD = item.price;

        // Convert the sent ETH amount to USD
        uint256 ethAmount = msg.value;
        uint256 ethAmountInUSD = PriceConverter.getConversionRate(ethAmount, priceFeed);

        require(ethAmountInUSD >= itemPriceInUSD, "Insufficient funds.");

        s_sendersAddress.push(msg.sender);
        s_peopleWhoBought[msg.sender] += ethAmountInUSD;
        walletAmmount += ethAmountInUSD;

       
}

}

Here's the revert when I try to do the transaction on Remix EVM. Capturex

However, it worked just once when I tried it on the test net.

Check it out: https://sepolia.etherscan.io/tx/0xbeaa569b48baedcce4cb3ddc8e1f42bca98131b1e02fcbd73c127b313b29aac4

Capturey

4
  • Not a solution to your specific problem but i strongly suggest you to keep the products outisde the contract, since it's being payd with ETHER you can pass the value of the product in ETH/USD. Commented Jun 2, 2023 at 0:09
  • You can't use price feeds on a local deployment - look at docs.chain.link/data-feeds/price-feeds/addresses.
    – Ape Toshi
    Commented Jun 2, 2023 at 10:10
  • yes but the issue is still coming when I deploy it on testnet. It worked only once on the testnet.
    – Brexela
    Commented Jun 2, 2023 at 10:17
  • Have you checked whether you have enough balance in the Remix address you're calling from? if all else is equal and the error message indicates your balance may be lower than the amount youre sending that may be it?
    – ZeusLawyer
    Commented Jun 4, 2023 at 23:52

1 Answer 1

1

I was accessing the priceFeed address without specifying it while deploying the contract.

Your Answer

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

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