17

In solidity it's obvious how to get a single string returned from a function. But, I'd like to have the smart contract return multiple string values. Is there a way to do this?

22

There are a few types of string values that you may be referring to.

  • bytes1 - bytes32: fixed size.
  • bytes or string: dynamically sized.

Solidity supports functions with multiple return values.

contract MultiReturner {
    function getData() constant returns (bytes32, bytes32) {
        bytes32 a = "abcd";
        bytes32 b = "wxyz";
        return (a, b);
    }

    function getDynamicData() constant returns (bytes, bytes) {
        bytes a;
        a.push('a');
        a.push('b');
        a.push('c');
        bytes b;
        b.push('x');
        b.push('y');
        b.push('z');
        return (a, b);
    }
}

You can do the same with bytes or string but with the limitation that solidity does not support returning dynamically sized values to other functions. This means that you would be able to use the getData function from within another contract and retrieve the return values but you would not be able to retrieve the return values from getDynamicData from within a contract.

contract UsesMultiReturner {
    function doIt() {
        mr = MultiReturner(0x1234);

        // this will work
        var (a, b) = mr.getData();

        // this won't work
        var (a, b) = mr.getDynamicData();
    }
}

You can however retrieve the return values from both getData and getDynamicData when call from outside of the blockchain.

  • since returned type is bytes32, should we typecast var into bytes32?@Piper Merriam. – alper Jan 11 '17 at 15:29
  • 2
    In solidity var can be used to delegate selecting the appropriate type to the compiler. a and b will be set as bytes32 by the compiler since the compiler knows that mr.getData() will return type (bytes32, bytes32) – Piper Merriam Jan 11 '17 at 15:35
  • var is now deprecated. Is there an update on how to return multiple values using 0.4.21? – JohnAllen Mar 23 '18 at 17:14
  • Solidity 0.4.23, but I'm not sure if it actually does the same thing. – digitaldonkey May 23 '18 at 23:59
1

You can use Seriality library. Seriality is a library for serializing and de-serializing all the Solidity types in a very efficient way which mostly written in solidity-assembly

1- By means of Seriality you can easily serialize and deserialize your variables, structs, arrays, tuples, ... and pass them through the contracts and libraries.

2- You can decouple your contract from libraries by serializing parameters into a byte array.

3- It also can be used as an alternative for RLP protocol in Solidity.

Here is a sample :

pragma solidity ^0.4.16;

import "./Seriality.sol";

contract StringsReturn is Seriality {

function stringCaller() public returns( string memory out1,
                                        string memory out2,
                                        string memory out3,
                                        string memory out4,
                                        string memory out5)
                                        {

    bytes memory buffer = new bytes(320);
    uint offset = stringCallee(buffer);

    //deserializing
    out1 = new string (getStringSize(offset, buffer));
    bytesToString(offset, buffer, bytes(out1));
    offset -= sizeOfString(out1);

    out2 = new string (getStringSize(offset, buffer));
    bytesToString(offset, buffer, bytes(out2));
    offset -= sizeOfString(out2);

    out3 = new string (getStringSize(offset, buffer));
    bytesToString(offset, buffer, bytes(out3));
    offset -= sizeOfString(out3);

    out4 = new string (getStringSize(offset, buffer));
    bytesToString(offset, buffer, bytes(out4));
    offset -= sizeOfString(out4);

    out5 = new string (getStringSize(offset, buffer));
    bytesToString(offset, buffer, bytes(out5));

}

function stringCallee(bytes memory buffer) public returns (uint buffer_size) {

    string memory out1  = new string(32); 
    string memory out2  = new string(32);        
    string memory out3  = new string(32);
    string memory out4  = new string(32);        
    string memory out5  = new string(32);

    out1 = "Come on baby lets dance!";
    out2 = "May I buy you a drink?";
    out3 = "I am an itinerant programmer";
    out4 = "Inam javab lashi!";
    out5 = "Bia inja dahan service";

    // Serializing
    buffer_size =  sizeOfString(out5) +
                   sizeOfString(out4) + 
                   sizeOfString(out3) + 
                   sizeOfString(out2) +
                   sizeOfString(out1);

    uint offset = buffer_size;

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

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

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

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

    stringToBytes(offset, bytes(out5), buffer);

    return buffer_size;
  }    
}

This is the output of stringCaller()

"0": "string: out1 Come on baby lets dance!",
"1": "string: out2 May I buy you a drink?",
"2": "string: out3 I am an itinerant programmer",
"3": "string: out4 Inam javab lashi!",
"4": "string: out5 Bia inja dahan service"

And here is the buffer :

    42696120696e6a6120646168616e207365727669636500000000000000000000
    0000000000000000000000000000000000000000000000000000000000000016
    496e616d206a61766162206c6173686921000000000000000000000000000000
    0000000000000000000000000000000000000000000000000000000000000011
    4920616d20616e206974696e6572616e742070726f6772616d6d657200000000
    000000000000000000000000000000000000000000000000000000000000001c
    4d617920492062757920796f752061206472696e6b3f00000000000000000000
    0000000000000000000000000000000000000000000000000000000000000016
    436f6d65206f6e2062616279206c6574732064616e6365210000000000000000
    0000000000000000000000000000000000000000000000000000000000000018

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.