2

again, I hope this is not a double posting. I ran into some issue with some smart contracts. Basically I only wanted to store multiple variables using a smart contract, examples below:

For completeness the struct first:

struct Userprofile{ 
    string id; 
    string fname;
    string mname;
    string lname;
    string genderValue;
    string dob;
    string sha256hash;
} 
mapping(string => Userprofile) ProfileData;

Then the set function:

 function setData(string uid,string firstname,string middlename,string lastname,string gvalue,string dobVal,string hashVal) { 
    ProfileData[uid].id = uid;
    ProfileData[uid].fname = firstname;
    ProfileData[uid].mname = middlename;
    ProfileData[uid].lname = lastname;
    ProfileData[uid].genderValue = gvalue;
    ProfileData[uid].dob = dobVal;
    ProfileData[uid].sha256hash = hashVal;
}

When testing the code in the solidity realtime compiler, everything is good and works. I can successfully store stuff and retrieve it again with e.g. this function:

function getFirstname(string uid) constant returns (string retFirstname) {
    retFirstname = ProfileData[uid].fname;
    return retFirstname;
}

When uploading the entire thing into the JS console on my geth-node I can mine the contract successfully and interact with it - all cool thus far.

But the challenge I have is that if I'm trying to retrieve any data, all functions return """...

I've seen that when I limit the set function to only two variables, this problem disappears. The second I aim for more then two, the problem is there again.

Maybe someone knows what that is... And besides, my default account holds 16k Ether...

Thanks!

  • 1
    Not sure what it is. Can you provide Details on how you test this? I usually create the struct first and put in the mapping like this: ProfileData[uid] = UserProfile(uid, firstname, middlename, lastname, gvalue, dobVal, hashVal); Not sure why this would work better, but since its always worked for me, maybe you can try it this way. – Max Binnewies Feb 7 '17 at 11:21
  • Thanks Max! I'm basically testing it in the JS Console calling directly the functions. Setting data results in a TX - which gets perfectly mined. Calling the get functions then yields nothing... Same is true via web3... Let me try your example and I'll see if there is a different output! – Borinho Feb 7 '17 at 11:34
  • i am facing same issue, previously its working fine, but from last Friday its stopped, i didn't find anything on this. – Sagar Feb 7 '17 at 13:17
  • Really strange! I've played around with both the solidity version at the realtime complier and the version of geth... Still no luck... – Borinho Feb 7 '17 at 13:37
1

I've pasted that specific code into browser-solidity and it seems to work fine for me.

There's a number of possibilities. For example, there could be something in geth that's converting the uid you give into something else (since it's expecting a string, a plain number might give a different value.) It's also possible the number of strings (which are not Solidity's best type) has messed things up. Or it messes things up in specific versions of solidity.

Here's some suggestions:

  1. Try putting public in the mapping, like mapping(bytes32 => Userprofile) public ProfileData; This will automatically create even better getters for you, that will return the whole ProfileData without having to mess with manual getters. This works for almost everything except recursive structs
  2. Note that in the above, I use bytes32 instead of string. This trick won't work if the mapping key is a string. However, what specifically is a uid? Is it a username? A number? If it's just a number, then you could get away with a uint. If it's a username, then you can hash the name somehow (sha3 would be best) in the frontend and use the result (a bytes32) as your key.
  3. You can probably get away with a lot less strings. You have three strings for the name, but you really only need one. The front end can separate or rearrange as needed. And on that subject, some people/cultures don't have three names like this, so having one long string is more compatible. Similarly, date-of-birth might be better as a number representing UNIX time, since you can actually do math in-contract with that. (That, and there are many incompatible formats someone might stick in). genderValue is probably not best to be a string, or otherwise people might enter any number of variants on the same gender (i.e. "woman", "WOMAN", "girl", "F", "female", "f", etc.) sha256hash can just be a bytes32, since that's what it is.

Hope this helps!

  • Hey Matthew, thanks for your support here. I've tried using public, but browser solidity throws immediately an error, not really sure why. And besides, you are completely right I'm really lazy on declaring the variables correctly. Sting just works for the initial version :) – Borinho Feb 8 '17 at 6:44
  • If you're using a string as the mapping key, browser-solidity will immediately complain, because that doesn't work on public mappings yet. – Matthew Schmidt Feb 8 '17 at 12:50

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.