2

Goal: I wish to store an array of names with an address in a smart contract. It's more like Key-Value pairs where addresses are paired with a list of type strings.

Can I use mapping to implement this? See below for instance.

mapping(address => strings[]) userAddress2UserNames;

Or, there is a different approach to it?

Experiments I performed

I got no error when I compiled the above code but when I call a method which returns string[] from this mapping I got an error stated below.

TypeError: This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature.

I'm not much aware of this version but I am assuming I should not do production level implementation with it because may be it's not stable. (Please correct me if I am wrong)

Please suggest me a way to achieve my goal.

  • 1
    Currently you cannot use strings like that. A string itself is an array of bytes and you are mapping an array of an array of bytes. Solidity does not have the feature to do that but syntactically it is alright. Since it is a feature that is still being developed that is why you are getting that error. Which version of solidity are you using i.e what is the number beside pragma solidity? – R.D Oct 9 '18 at 12:01
  • I'm using 0.4.24 – Gagan Oct 9 '18 at 12:25
  • So I really want to implement such mapping. What are the other ways of doing it? Structs? 2-d array of type bytes32? I'm quite confused. – Gagan Oct 9 '18 at 12:28
  • Try the same code in 0.4.25 or 0.5.0 then you may be able to do it. I don't know anything more sorry. – R.D Oct 9 '18 at 12:33
5

How long are the user names? Maybe you can use bytes32 instead of string (each username would be limited up to 32 chars). By doing this, you wouldn't be combining two levels of dynamic arrays, which is not permitted in the current version.

2

The compiler will generate automatically getters for variables declared as public.

mapping(address => strings[]) userAddress2UserNames;

In this case the getter will look like

function userAddress2UserNames(address _addr, uint _index);

You have to provide an address and index to the array.

  • How can we push data in the mapping? userAddress2UserNames[msg.sender] = ? How to push data here? – Shubham Chadokar Oct 10 '18 at 4:26
  • @ShubhamChadokar Since it is a storage array you can push to it: userAddress2UserNames[msg.sender].push("name"). If you have more doubts it is better if you ask a new question. – Ismael Oct 10 '18 at 5:22
1

As it is suggested by @Patricio use bytes instead of string.
At current versions there are many limitations on string use. So better use bytes.
What you want to achieve is One to many mapping. But mapping are unique and you can't map a key with many values, so you have to use struct in this case.
Follow the below link they have explained it very well.
https://ethereum.stackexchange.com/a/38842/24373

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.