0

My contract has structs for products, companies etc. The product struct has a 'quant' var to store quantity of the product ordered, and an array of quant size called clicks, that's supposed to track the no. of times that piece of product is checked. A function 'ShowPDetials' is supposed to retrieve that product's data from a mapping, and each time its called, it takes a piece number and adds 1 to that spot in the array, therefore tracking no. of checks on that particular piece.

The issue is that when i call PDetails, that spot in the array shows 1 but when i call it again, it still shows 1 instead of 2. If i call it again with another piece number, the new spot shows 1 and old spot turns back into 0. Basically, the count is working only once in one spot, and isn't actually changing the numbers by 1 and storing it that way to iterate higher in the future. My task is to update the piece's spot each time the function is called with given piece number. Code below:

struct Product {
        uint PId;
        string PName;
        string Brand;
        uint PQuant;
        uint[] clicks;
        SCSection[] SChain;
    }

function StoreProduct(uint CompanyId, string memory ProductName, string memory PBrand, uint quant, uint FId, uint To_Id, string memory EmployeeId, string memory TaskDetails, string memory Current_Location) public returns(uint ProductId) {
        ProductId = PmapSize+1;
        Product storage p = Pmap[ProductId];
        p.PId = ProductId;
        p.PName = ProductName;
        p.Brand = PBrand;
        p.PQuant = quant;
        for (uint256 i = 0; i < quant; i++)  {
            p.clicks.push(0);
        }
        p.SChain.push(SCSection(PmapSize+1, FId, To_Id, EmployeeId, TaskDetails, Current_Location, block.timestamp, block.timestamp));
        PmapSize += 1;
        Cmap[CompanyId].CProducts.push(ProductId);
    }

function showPDetails(uint pid, uint piece_num) public returns(Product memory p)  {
        p = Pmap[pid];
        p.clicks[piece_num-1] += 1;
    }

2 Answers 2

0

The issue with the showPDetails function is with understanding how the Solidity language handles state changes and returns values.

In Solidity, functions that modify state (altering variables, updating mappings, arrays, etc.) cost gas and don't return anything to the caller by default. When you're calling showPDetails, you're expecting it to return a Product type, but your function is declared as returns(Product memory p), which doesn't correctly match the Solidity syntax.

The solution is to separate the state-changing part from the retrieval part into 2 different functions.

1
  • returns (Product memory p) is not part of the function declaration, it only declares the return value's type. Your function is indeed declared to be state-writing. The code should work, and it's a function that pays gas. Dec 6, 2023 at 9:14
0

function showPDetails(uint pid, uint piece_num) is not declared as a view or pure function. It's state-writing, and should work. The rest of the code won't compile, however. There's multiple errors, and you haven't declared types for half your variables.

By the way, do use more letters in variable declarations. You can use showProductDetails instead of showPDetails, we won't run out of alphabet letters ;-)

1
  • Oh nono I've declared everything, just didn't put it all here since it'll get long. Thanks for the tip, I'll change my var names XD Dec 7, 2023 at 5:43

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.