6

Since I can't seem to get my contract to return a string array in any of its methods, I'm just going to serialize the array and return it as a string or bytes.

I've tried various for loop methods to do this but I can't seem to concatenate strings either.

What's the best way to serialize an array of strings in Solidity?

I have a function like this that isn't working:

/* inside my contract */

string[] myArray;

function serializeArray() returns (string serializedArray) {
  uint arrayLength = myArray.length;
  string serialized = '[';

  for (uint i = 0; i < arrayLength; i++) {
    serialized += '"';
    serialized += inbox[i];
    serialized += '"';

    if (i < arrayLength) {
      serialized += ',';
    }
  }
  serialized += ']';

  return serialized;
}
6

This is not going to work in Solidity. The += operator is not implemented for strings, you need to use a library that allows to concatenate strings; I think the most popular is this one. There is an example of how to use concatenation here.

I'm not sure what you're trying to do, but that kind of concatenation is expensive. Wouldn't it be enough to have two methods:

getStringsLength() returns (uint) and getStringByIndex(uint index) returns (string), and retrieve the strings in a loop? You can then do the concatenation outside of the contract (probably cheaper).

Solidity:

string[] myArray;

function getStringsLength() returns (uint) {
    return myArray.length;
}

function getStringByIndex(uint index) returns (string) {
    if (index < myArray.length){
        return myArray[index];
    }
    return "";
}

Solidity-consumer pseudocode:

strings_to_serialize = []
for (int i=0; i<contract.getStringsLength(); i++)
    strings_to_serialize.append(contract.getStringByIndex(i))
# process the strings here
  • Interesting idea. I may even like that better than having my contract return an array. In the future when public methods can return string arrays, will it simply be cheaper to return the whole array rather than fetching on item at a time in a loop? – jaybee Oct 24 '16 at 17:18
  • I guess so, because then it can be optimized compiler-side somehow? But I honestly am not sure – 4gn3s Oct 25 '16 at 9:23
1

You can use Seriality library

Here is a sample :

pragma solidity ^0.4.16;

import "./Seriality.sol";

contract SerialitySample is Seriality {

   function testSample1() public returns(int n1, int8 n2, uint24 n3,  string n4,string n5) {

    bytes memory buffer = new  bytes(200);
    string memory out4  = new string(32);        
    string memory out5  = new string(32);
    n4 = new string(32);
    n5 = new string(32);
    int     out1 = 34444445;
    int8    out2 = 87;
    uint24  out3 = 76545;
    out4 = "Copy kon lashi";
    out5 = "Bia inja dahan service";

    // Serializing
    uint offset = 200;

    intToBytes(offset, out2, buffer);
    offset -= sizeOfInt(8);

    uintToBytes(offset, out3, buffer);
    offset -= sizeOfUint(24);

    stringToBytes(offset, bytes(out5), buffer);
    offset -= sizeOfString(out5);

    stringToBytes(offset, bytes(out4), buffer);
    offset -= sizeOfString(out4);       

    intToBytes(offset, out1, buffer);
    offset -= sizeOfInt(256);

    // Deserializing
    offset = 200; 

    n2 = bytesToInt8(offset, buffer);
    offset -= sizeOfInt(8);

    n3 = bytesToUint24(offset, buffer);
    offset -= sizeOfUint(24);

    bytesToString(offset, buffer, bytes(n5));
    offset -= sizeOfString(out5);

    bytesToString(offset, buffer, bytes(n4));
    offset -= sizeOfString(out4);

    n1 = bytesToInt256(offset, buffer);
}

}

output buffer :

00000000000000000000000000000000000000000000000000000000020d949d 436f7079206b6f6e206c61736869000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000e 42696120696e6a6120646168616e207365727669636500000000000000000000 0000000000000000000000000000000000000000000000000000000000000016 012b0157

"1": int256: n1 34444445

"2": int8: n2 87

"3": uint24: n3 76545

"4": string: n4 Copy kon lashi

"5": string: n5 Bia inja dahan service

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.