0

I'm new in solidity, I want to ask, in my case I want to store a data that may contain the same user ID but different value inside it each transaction, here is my smart contract:

pragma solidity 0.5;
contract userID{
  struct User {
        uint256 uid;
        bytes32 item;
      }
  mapping (uint256 => User) public  users;
  uint counter = 0;
  function sendReview(uint256 _uid, bytes32 _item) public{
      User storage useritem = users[counter];
      useritem.uid= _uid;
      useritem.item= item;
      counter++;
  }
   function getitem(**uint256 _uid**) public view returns( uint256, bytes32){
       **User storage users._uid**;
      return(users.uid, users.item);
  }
}

I want to get the item based on the uid that inserted into the function, how can I do it? I've tried a several way in 'User storage users._uid' but didn't work at all, or is there any better way to do it?

EDIT:

I want store the data like:

user[0] = ["1","apple"]
user[1] = ["1","orange"]
user[2] = ["2", "grape"]

so the get function if I set the value of uid into 1 then the result will be:

["1","apple"],
["1","orange"]
2
  • in your question you indicate that the data may include several items with the same uid. If you search for items based on the uid your search may return several results, is that what you are looking for?
    – Jaime
    Mar 16, 2021 at 7:12
  • yes, that's what I looking for, so It will return several results Mar 16, 2021 at 7:16

1 Answer 1

2

Instead of using a counter, just create a mapping of the uid to a byte32 array of userItems. Then when getting the items, you provide the uid and you get the list of items for that user.

This can be achieved with the code below. I test it on remix.

pragma solidity 0.5;
contract userID{
 
mapping (uint256 => bytes32[]) public  users;

function sendReview(uint256 _uid, bytes32 _item) public{
    users[_uid].push(_item);
}

function getitem(uint256 _uid) public view returns(bytes32[] memory){
    return(users[_uid]);
    
}

}

If you want to return structures then you can use this:

pragma experimental ABIEncoderV2;
pragma solidity 0.5;
contract userID{

struct user {
    uint256 uid;
    bytes32 item;
} 

mapping (uint256 => user[]) public  users;

function sendReview(uint256 _uid, bytes32 _item) public{
    user memory newUser = user(_uid,_item);
    users[_uid].push(newUser);
}

function getitem(uint256 _uid) public view returns(user[] memory){
    return(users[_uid]);

}

}

Hope it helps.

8
  • what if the data type that will be inserted not only bytes32? is that possible? or there is a data type to replace the "bytes32" as an array? In this case the array will store 2 value, uid as uint256 and item as bytes32 Mar 16, 2021 at 9:45
  • you can use an array of structs, but you will be adding redundant information by adding again the user id, no? The way I presented it makes it clear that the array of bytes32 is indexed by an unique user id. Notice that you will use as input uid and you will get the same uid number in one of your responses. There is no need to do this and will cost you 20000 gas extra per transaction when using the sendReview function
    – Jaime
    Mar 16, 2021 at 10:04
  • yes, I know, but I'm trying to try what if I input multiple data not only one kind of data, its just for study purposes, I don't mind about gas, yet, thank you by the way Mar 16, 2021 at 10:37
  • See my updated answer for recovering the structure. Hope this helps
    – Jaime
    Mar 16, 2021 at 11:17
  • I'm sorry, but my cakeshop compiler shows error UnrecognizedPropertyException: Unrecognized field "components" (class com.jpmorgan.cakeshop.model.ContractABI$Entry$Param), not marked as ignorable (4 known properties: "indexed", "type", "name", "internalType"]) I tried to google it, but can't find anything Mar 16, 2021 at 11:47

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.