1

solidity mapping does not persist

I have this solidity code

contract Starting { //pragma solidity ^0.6.12

    struct itemStatus {
        bool created;
    }
    mapping (bytes => itemStatus) public item;
    
    bool[] public boolArray;    

    function start(bytes memory itemId) public returns (bool[] memory) {
        boolArray.push(item[itemId].created);
        if (item[itemId].created) {
            boolArray.push(item[itemId].created);
            return boolArray;
        } else {
            item[itemId] = itemStatus(true);
            boolArray.push(item[itemId].created);
            return boolArray;
        }
    }
}

frontend javascript code is

  toStart: function () {
    let Instance;
    App.contracts.Starting.deployed().then(function (instance) {
      Instance = instance;
      return Instance.start.call(itemId);
    }).then(function (result) {
      console.log(result);
    }).catch(function (err) {
      console.log(err.message);
    });
  },

The first time I call toStart, I would expect [false, true] and the second time I call with the same itemId [false, true, true, true] and third time [false, true, true, true, true, true]. However, the result is always [false, true] irregard how many times I call toStart. It seems item[itemId] = itemStatus(true) and boolArray.push(item[itemId].created) changes are never stored/persisted. Why is it so? How to change the code to get the expected result? Many thanks in advance.

2 Answers 2

2

Change this:

Instance.start.call(itemId)

To this:

Instance.start.send(itemId)
1

Assuming the ethers version you're using is the older version, the error arises because ethers.js makes a distinction between constant calls and non constant(state writing) calls using call and send. When trying to call a constant method, call is used and when calling a non constant method, send is used.

Because your contract changes the state in boolArray.push(item[itemId].created);, the function is non constant and you need to use the send.

Ethers v5 : Ethers v5 does not make this distinction. You can call both methods the same way but the return values would be Promise<any> for constant and Promise<TransactionResponse> for non constant functions.

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.