19

I know I can return dynamic byte arrays in Solidity, such as in the following code:

function createMemoryArray(uint size) returns (bytes) {
    // Dynamic memory arrays are created using `new`:
    uint[2][] memory arrayOfPairs = new uint[2][](size);
    // Create a dynamic byte array:
    bytes memory b = new bytes(200);
    for (uint i = 0; i < b.length; i++)
        b[i] = byte(i);
    return b;
}

But is there a way to return something like a dynamic array of strings? I feel like this is just an implementation detail in Solidity, but it would be great if it just serialized everything nicely for me.

10

Is it possible to return an array of strings ( string[] ) from a Solidity function?

Not yet, as this requires two levels of dynamic arrays (string is a dynamic array itself). Doc

However you can return an Array of Bytes32 ( fixed size of 32 byte) So you can try to do something like this ( you can copy paste on Remix to test it )

pragma solidity ^0.4.11;
contract ArrayOfBytes32 {
    address creator;
    bytes32[10] bytesArray; // size must be fixed

    function ArrayRR() 
    {
        creator = msg.sender;
        uint8 x = 0;
        while(x < bytesArray.length)
        {
            bytesArray[x] = "myString"; 
            x++;
        }
    }

    function getArray() constant returns (bytes32[10])
    {
        return bytesArray;
    }

    function getValue(uint8 x) constant returns (bytes32)
    {
        return bytesArray[x];
    }
}

Note that you will have to use web3.toAcsii() doc to convert the result if you use web3 to interact with your contract

  • 1
    Huh, I never would've thought to check the doc FAQs. Nice find and interesting solution! – user9402 Jun 6 '17 at 13:35
  • 1
    Why I can't return a dynamic array of of bytes32 (bytes32[])? – Robert Zaremba Aug 21 '17 at 14:41
  • 2
    You can return a dynamic array of of bytes32 (bytes32[]). What you can't is returning an object which combines two levels of dynamic arrays. – Robert Zaremba Aug 21 '17 at 18:02
  • @RobertZaremba But isn't bytes32 an array itself? Then bytes 32[] is a two dimensional array – Andrey Mar 21 '18 at 14:16
  • 1
    @Andrey Problem is with two levels of dynamic arrays, not a two dimensional arrays. You could have function return two dimensional array of 10 uints each without problem - but you cannot have two dimensional array where both arrays are dynamic. Type "bytes32" just indicate that it allocates 32 bytes in the memory, so it is not dynamic variable - you always know that it will take 32 bytes of memory, therefore it is static variable (cannot change size during runtime). That's why it works :) – Oliver Rydzi Dec 10 '18 at 17:38
1

It is an old issue... But, for newcomers and for completeness sake, there is no problems in Solidity to return dynamic arrays of pairs, or dynamic arrays of strings, if one uses the modern compiler (tested with 0.5.6) and experimental ABI pragma:

    pragma experimental ABIEncoderV2;

    ...

    function createMemoryArray(uint size) public pure returns (uint[2][] memory) {
        uint[2][] memory b = new uint[2][](size);
        for (uint i=0; i < b.length; i++) {
            b[i][0] = i;
            b[i][1] = i * 2;
        }
        return b;
    }

    function createStringArray(uint size) public pure returns (string[] memory) {
        string[] memory b = new string[](size);
        for (uint i=0; i < b.length; i++) {
            b[i] = "test";
        }
        return b;
    }
0

Return dynamic arrays of structure in a function

pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract Money {
  struct People{
    uint id;
    string name;
    uint amount;
  }
  mapping (uint => People) public peoples;
  event votedEvent(uint indexed _candidateId);
  uint public candidateConut;

  constructor() public {
    candidateConut = 0;
    addCandidate("Holder 1");
    addCandidate("Holder 2");
  }
  function addCandidate(string memory _name) public {
    peoples[candidateConut] = People(candidateConut,_name,0);
    candidateConut++;
  }
  //return Single structure
  function get(uint _candidateId) public view returns(People memory) {
    return peoples[_candidateId];
  }
  //return Array of structure Value
  function getPeople() public view returns (uint[] memory, string[] memory,uint[] memory){
      uint[]    memory id = new uint[](candidateConut);
      string[]  memory name = new string[](candidateConut);
      uint[]    memory amount = new uint[](candidateConut);
      for (uint i = 0; i < candidateConut; i++) {
          People storage people = peoples[i];
          id[i] = people.id;
          name[i] = people.name;
          amount[i] = people.amount;
      }

      return (id, name,amount);

  }
  //return Array of structure
  function getPeoples() public view returns (People[] memory){
      People[]    memory id = new People[](candidateConut);
      for (uint i = 0; i < candidateConut; i++) {
          People storage people = peoples[i];
          id[i] = people;
      }
      return id;
  }
}
  • I don't encourage you to use this in main net, cause it is experimental and a lately article has shown a bug in it. – Majd TL Aug 28 at 14:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy