0

I have a simple contract that has a setter and getter for a struct called Institution. I have removed most of the properties am using, to simplify the question.

pragma solidity ^0.4.22;

contract Example{

struct Institution {
    bytes32 name;
    bool exists;
}

event AddedInstitution(bytes32 name);

mapping(bytes32 => Institution) institutions;

//add an institution
function addInstitution(
    bytes32 name,
    bytes32 upi
) public {
    require(!isInstitutionExists(upi));
    institutions[upi].name = name;
    institutions[upi].exists = true;
    emit AddedInstitution(name);

}
//get an institution
function getInstitution(bytes32 upi) public constant returns (bytes32 name){
    require(isInstitutionExists(upi));
    return (
    institutions[upi].name
    );

}
//is institution exist
function isInstitutionExists(bytes32 upi) private constant returns (bool){
    if (institutions[upi].exists) {
        return true;
    }
    return false;
}

}

The setter works as expected. It adds a new institution and emits an event. But when I call the getter and give it a upi, it returns a location address of the name of the institution instead of giving me the exact name, as shown below:

'0x4d6f6920556e7669766572736974790000000000000000000000000000000000'

The results are consistent in both truffle console and browser.

What is wrong with my code?

Sean
  • 165
  • 1
  • 6

1 Answers1

0

That's not an address; it's just the hexadecimal representation of the string. You can use web3.toAscii to convert it to a displayable string.

> web3.toAscii('0x4d6f6920556e7669766572736974790000000000000000000000000000000000')
'Moi Unviversity'
user19510
  • 27,999
  • 2
  • 30
  • 48
  • Do i have to use this method all the time or is there a way to query the name and obtain it directly as 'Moi University' or whatever the value? – Sean Jun 21 '18 at 23:15
  • That's the actual value that's stored. You could convert it to a string first so whatever client you're using will do the conversion automatically. – user19510 Jun 21 '18 at 23:19
  • (am new to solidity btw) Do you mean changing the data type of name from bytes32 to string instead? If possible could you answer with some code examples? or a reference of where I can read more on this... – Sean Jun 21 '18 at 23:24
  • Yes, I mean either using string instead of bytes32 everywhere, or converting from bytes32 to string just in your accessor function. But there's no reason to do this. bytes32 is a fine way to store a string that has a maximum length of 32 bytes. You just need to convert it to ASCII before displaying it. – user19510 Jun 21 '18 at 23:26
  • Does solidity have a way to covert this at contract level or do I have to use web3.toAscii at front end level? – Sean Jun 21 '18 at 23:31
  • You can certainly use bytes32 everywhere and then convert it in the getter (see https://ethereum.stackexchange.com/a/31292/19510), but don't do that. It just wastes gas moving bytes from one place to another when you can just do it on the front-end for free. – user19510 Jun 21 '18 at 23:36
  • As a side note, I have used web3.toAscii and I get an error in browser that no such method. Using web3.utils.toAsciiworks, as indicated in this question. – Sean Jun 21 '18 at 23:52
  • web3.toAscii is for the current web3.js released version (0.2x.x). For the 1.0 beta versions, web3.utils.toAscii is correct. – user19510 Jun 22 '18 at 00:10