0

A msg.sender can create multiple Struct Item . What would be best way to store the Item ?

Currently I'm using

struct Item {
    uint256 amt;
    bool isActive;
    address owner;
}
Item[] public items;
function createItem(uint amt) returns(uint a){
   items.push(Item({
      ...
   }))
   return (items.length);
}

But createItem returns a tx hash as it's not mined yet.

Calling a items.length after mining completes won't guarantee me the id.

I also tried adding it in mapping but mapping don't accept Struct Arrays

Item[] public itemStack;
mapping(address => itemStack) public items; //TypeError: Name has to refer to a struct, enum or contract.
...
items[msg.sender].push(...)
  • 1
    I think your second version should be mapping(address => Item[]), right? For your first question, you pretty much have to log an event and check the transaction receipt for that event. (Last I checked, this was not straightforward in web3.js.) – user19510 Jan 19 '18 at 0:38
1

You need to use an event/log to get return values from non-constant functions which is a bit involved but you can check here in the doc for a description.

In your case you will need to declare an event such as event LogItemCreated(address indexed sender, uint itemId); in the global context where your global/storage vars are declared. Then before the return statement in createItem() do LogItemCreated(msg.sender, items.length);.

Then in your tests or however you're calling the contract you need to listen for that event. I do this with this JS function which you can paste into node or a truffle test file.

const listenForEvent = event => new Promise((resolve, reject) => {
    event.watch((error, response) => {
        if (!error) {
            resolve(response.args)
        } else {
            reject(error)
        }
        event.stopWatching()
    })
})

Then in node or your test file do this before or directly after doing the transaction listenForEvent(contractInstance.LogItemCreated({sender: txSenderAddress}). Where contractInstance is the contract you're making the transaction on and txSenderAddress is the address of the account that made the transaction to createItem(). This should return the item id as expected.

It's a bit long winded but it's worth learning about events since they're the only way to get return values from 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.