5

When trying to return a struct with Solidity like this:

function getAssetStructById(uint256 assetId) constant returns (asst _asset) {
    return (assetsById[assetId]);
}

This is the compilation error it throws:

Error: Internal type is not allowed for public or external functions.

So, how can I get the data of the struct returned? I tried returning every field of the struct but this is not working anymore once you reach 9 data fields, getting the error:

'Stack too deep' compiler error.

Ref.: Is there any limitation for the number of the return values from Solidity functions?

This is the struct I would like the function to return:

struct asst {
    uint256 assetId;
    uint256 next;
    uint256 prev;
    uint256 timestampCreation;
    address assetOwner;
    address issuer;
    string content;
    uint256 sellPrice;
    assetState state;
}

Any idea how to do that on Solidity? Thx!

Ref.: Return a struct from a Solidity Contract

0

3 Answers 3

7
+50

Update:

See here. We can return structs but only for internal calls.

Returning structs in new version in Solidity

In this snippet, function tryIt() returns true after a successful compile. It's just making an internal call (success). getAssetStructById() fails when called from outside.

pragma solidity 0.4.17;

contract Test {

    enum assetState{something}

    mapping(uint256 => asst) assetsById;

    struct asst {
        uint256 assetId;
        uint256 next;
        uint256 prev;
        uint256 timestampCreation;
        address assetOwner;
        address issuer;
        string content;
        uint256 sellPrice;
        assetState state;
    }

    function getAssetStructById(uint256 assetId) public view returns (asst _asset) {
        return (assetsById[assetId]);
    }

    function tryIt(uint id) public view returns(bool success) {
        asst memory a = getAssetStructById(id); 
        return true;
    }
}

Hope it helps.

1
10

You currently cannot return structs in Soldity as the answer to the question that you linked correctly outlines. But you can take your struct apart and return the individual elements (Solidity does support multiple return values):

function getAssetStructById(uint256 assetId) constant returns (
uint256 assetId,
uint256 next,
uint256 prev,
uint256 timestampCreation,
address assetOwner,
address issuer,
string content,
uint256 sellPrice,
assetState state
) {
    return (assetsById[assetId].assetId, /*add other fields here*/);
}

We are currently limited in the number of total local variable, parameters and return values. You can only partially circumvent that by restructuring. More often than that it leads to the question: do you really need all that data on the blockchain? Storing e.g. a hash of a larger dataset might be sufficient. Also consider that every call costs quite a bit of gas if you pass a ton of parameters.

1
  • 3
    had same issue over a year ago. Had to do what this answer discusses. Another possibility is logging via events, for purposes of writing unit tests. (e.g. to check the state of a bunch of counters after each transaction). That's less gas and I appear to be able to get a few more items into an event as arguments than as a return value (possibly because of the optimizer)
    – Paul S
    Commented Jun 19, 2017 at 22:52
1

.You cannot return a structure in solidity you can use it only inside your contract, it's useful in maps and some stucturing, you can return a tuplet-like

for example,

 struct Student {
         string name,
        string something}
  Student o = Student("Naruto","Uzumaki",...);

.... then

 return (o.name,o.ninpo,..);
1
  • this is the same as the first answer above...
    – Paul S
    Commented Jun 22, 2017 at 23:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.