In my contract I have a mapping like this mapping(uint => myStruct)

I have a check function where I give a uint id and I want to get all the info in the struct (there are strings, addresses, uints, ...) with a call function in my truffle app.js.

What's the best way to do that? Can I convert every field to a string and send an array of strings? Should I make a separate getter for each field and use as many call functions?

For now I just return struct and I get invalid solidity type!: tuple

  • You can't return a struct in solidity, at least for the ucrrent version. so you need to return each value on its own. something lik e: return ( struct.member1,struct.member2) Commented Mar 6, 2018 at 10:48
  • Please note that there is work in progress for Solidity to support serialization of complex types blog.ricmoo.com/… Commented Mar 6, 2018 at 12:42
  • @MedMansour You can return each value separately in a single return? That changes everything if js can handle it! Commented Mar 6, 2018 at 12:46

4 Answers 4


You don't need an extra solidity function to get the info from a struct. You can call the struct directly using web3.

It helps if you have a function on the contract to get the amount of tokens otherwise you might be stuck using while instead of for. Lets assume you have a function to give you struct.length

var OwnableList = [];

//to get one struct entry you do this.

function getStructData(tokenId) {

    myContract.Ownables(tokenId, function(error, details) {
        if(details == undefined) {
            return false;
        } else {
            var name = details[0];
            var creator = details[1];
            var currentOwner = details[2];
            var isDestructible = details[3];
            var price = parseInt(details[4]);
            OwnableList.push({name: name, creator: creator, currentOwner: currentOwner, isDestructible: isDestructible, price: price});
    return true;

//to get all struct entrys you do this

function dumpStructData() {
    myContract.totalOwnables(function(error, total) {
        for(i=0; i<parseInt(total); i++) {

//now you can just read the struct

function showStruct() {

Apparently my question was misunderstood, but I solved the problem with the help of Mikko Ohtamaa in the comments.

For some reason I didn't realized I could return multiple variables (and of different types!) Once you know you can do this, there's no problem really. Javascript handles it very well.

My solution looks somewhat like this:

contract myContract {
  struct Ownable {
    string name;
    address creator;
    address currentOwner;
    bool isDestructible;
    uint price;

  mapping (uint => Ownable) public Ownables;

  function getOwnableInfo(uint OwnableId) public view returns (string, address, address, bool, uint){
    Ownable o = Ownables[OwnableId];
    return (o.name, o.creator, o.currentOwner, o.isDestructible, o.price);


And in the corresponding truffle, the call will return an array with the variables of the return in order:

myContractInstance.getOwnableInfo.call(ownableId).then((resultArray => {
  name = resultArray[0];
  creator = resultArray[1];
  currentOwner = resultArray[2];


  • Don't look too much into the Ownable o = Ownables[OwnableId];, I did that to increase readability, I don't think it's useful or a good thing at all.
  • If one of the data is a big number (typically a wei price), I convert it using bignumber's resultArray[4].toNumber() so that JavaScript can handle it.

the best way for adding something into a struct and get all the records is :

pragma solidity ^0.4.17;

contract test {
    struct Record {
        string name;
        string homeAddress;

    Record[] public records;

    function AddRecord(string Address , string Name) public {
        Record memory newRec = Record({
            name : Name,
            homeAddress : Address


    function recordsArrayLength() public view returns(uint256){
        return records.length;


and in your ui use this code :

first use let len = await test.methods.recordsArrayLength().call() and get the length of records array and then hit this code :

let records = []

for(let i=0;i<len;i++){
    records.push(await test.methods.records(i))

and now you have all the struct

  • So instead of returning the struct, you return an array with one struct inside? Commented Mar 6, 2018 at 12:00
  • yep that's right Commented Mar 6, 2018 at 18:33
  • I'm not sure how you understood that, but I don't want to add something into a struct, I just want to get all the info inside of it. Commented Jul 10, 2018 at 7:43

It's tangential to your question, but one of the best ways to organize data is a mapped struct with an index of keys. This makes it possible to access a particular record or verify its existence without knowing which row it's on and without searching through a list. The index is an unordered list of keys that makes it possible to count the keys and enumerate the keys that exist.

mapping(bytes32 => RecordStruct) public recordStructs;
bytes32 public recordKeys;

Have a look over here for some variants, implementation details and discussion of limitations and advantages of various approaches.

Are there well-solved and simple storage patterns for Solidity?

Also, though not shown in the examples, event emitters can make the storage state apparent to software clients. With comprehensive event logs, one can write the contract with the assumption that clients are aware of the complete state at all times. This reduces on-chain concerns considerably.

Hope it helps.

  • What do you mean "without knowing which row it's on" ? Your answer looks interesting but I'm not sure what you're trying to accomplish. Commented Jul 10, 2018 at 7:46
  • You're mapping(uint => myStruct) has structs stored by number and the question is about migrating to an array (also by number). I want to retrieve by key (e.g. "ORD002" or "0x123...") and I don't want to search. I also want a list and a count. Commented Jul 10, 2018 at 12:23
  • I think you misunderstood my question. I don't want to migrate, I have a struct with several data of multiple types, and I want to write a function to call with truffle in order to get all that info. Commented Jul 10, 2018 at 13:28
  • I wrote an answer about how I solved my problem, maybe you'll understand better what I meant. Commented Jul 10, 2018 at 14:01

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.