3

I have a bytes32[] array. I convert strings to bytes32 before they are added to the array as follows:

function stringToBytes32(string memory source) returns (bytes32 result) {
    assembly {
    result := mload(add(source, 32))
    }
}

which will turn the string into a hex like 0x5468697320697320612074657374206d65737361676520746861742077696c6c, for example.

However, if the string converted into bytes32 is over 32 characters, I don't know how to turn it back into its original string over 32 characters. Using web3.toAscii only brings back the first 32 characters.

  • This sort of thing could be awkward and costly to handle in a smart contract and it will lead to unwanted complexity in the contract. I would incline to the minimal smart contract design. Make the clients encode/decode the data into 32-byte chunks. – Rob Hitchens - B9lab Jul 8 '17 at 16:59
  • Say if I had messages of 128 characters in length that needed to be stored and called from a contract, would it be a horrible solution to have four bytes32[] arrays? If I can't use an array of strings. – ZhouW Jul 9 '17 at 1:15
  • If I understand correctly, it would be four bytes32, without the array or a bytes32[4]. Would be appropriate IMHO. – Rob Hitchens - B9lab Jul 9 '17 at 1:55
  • No, I was thinking of having multiple bytes32[] arrays (probably a bad idea). I need some way of storing many messages that are longer than 32 characters so I thought I would need to use arrays. – ZhouW Jul 9 '17 at 2:36
  • For the interface, work with one message at a time. For storage, arrays would probably be part of it. Have a look over here ethereum.stackexchange.com/questions/13167/…. – Rob Hitchens - B9lab Jul 9 '17 at 7:27
2
struct DocumentStruct{bytes32 string1; bytes32 string2; bytes32 string3;}
mapping(bytes32 => DocumentStruct) public documentStructs;

function StoreDocument(bytes32 key,bytes32 string1,bytes32 string2,bytes32 string3) onlyOwner returns (bool success) {
    documentStructs[key].string1 = value;
    documentStructs[key].string2 = name;
    documentStructs[key].string3 = name;
    return true;
}

function RetrieveData(bytes32 key) public constant returns(string,string,string) {
    var d = bytes32ToString(documentStructs[key].string1);
    var e = bytes32ToString(documentStructs[key].string2);
    var f = bytes32ToString(documentStructs[key].string3);
    return (d,e,f);
}
function bytes32ToString(bytes32 x) constant returns (string) {
bytes memory bytesString = new bytes(32);
uint charCount = 0;
for (uint j = 0; j < 32; j++) {
    byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
    if (char != 0) {
        bytesString[charCount] = char;
        charCount++;
    }
}
bytes memory bytesStringTrimmed = new bytes(charCount);
for (j = 0; j < charCount; j++) {
    bytesStringTrimmed[j] = bytesString[j];
}
return string(bytesStringTrimmed);
}

This works pretty well for me. I would agree that its a little complex to encode and decode, but just run your 32 byte array through it to get a string back

Edit - Here's some added stuff. A rather hacky way, but it might work for you. I'm sure Rob will yell at this answer though

  • The problem is it'll only return 32 characters. – ZhouW Jul 9 '17 at 3:01

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.