I'm trying to interact with this contract via web3.js.

Something like this answer seems to be the right path to take, but I can't figure out how to implement that logic in my contract.

When getAdopters() is called, I see the following error in my browser's console:

invalid solidity type!: tuple[16]

Here's the code where getAdopters() is called:

  markAdopted: function(owners, account) {
    var adoptionInstance;

    App.contracts.Adoption.deployed().then(function(instance) {
      adoptionInstance = instance;

      return adoptionInstance.getAdopters.call();

    }).then(function(owners) {
      for (i = 0; i < owners.length; i++) {
        if (owners[i] !== '0x0000000000000000000000000000000000000000') {
            $('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true);
            var loc = document.getElementById('owned-by');
            loc.innerHTML += owners[i];

    }).catch(function(err) {

Ultimately, how can I return the fields of the struct as separate return variables, and then access them using web3.js?

marked as duplicate by Ismael, flygoing, Richard Horrocks, Muhammad Altabba, Jitendra Kumar. Balla Feb 19 '18 at 10:10

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


Your question is pretty similar to this one:

How to return an array of structs (or an array of destructured structs) in Solidity

Look over the comments, particularly with regards to "pragma experimental ABIEncoderV2;"


Based on your comments, I think this is what you're looking for. The values from the structs will be returned to web3 as arrays of the struct values.

pragma solidity ^0.4.19;
contract Adoption {
    struct Pet {
        address owner;
        uint256 price;

    Pet[16] data;

    function Adoption() public {
        for (uint i = 0; i < 16; i++) {
            data[i].owner = msg.sender;
            data[i].price = i;

    function getAdopters() external view returns (address[],uint256[]) {
        address[] memory owners = new address[](16);
        uint256[] memory prices =  new uint256[](16);
        for (uint i = 0; i < 16; i++) {
            owners[i] = (data[i].owner);
            prices[i] = (data[i].price);
        return (owners,prices);

Some JS test code in test.js script:

module.exports = () => {
    const Adoption = artifacts.require('Adoption');
    return Adoption.deployed().then(function(instance) {
        adoptionInstance = instance;

        return adoptionInstance.getAdopters.call()
            .then(adopters => {
                const [ owners, prices ] = adopters;
                for (let i = 0; i < owners.length; i++) {
                    console.log(`owner=${owners[i]}, price=${prices[i].valueOf()}`);

I tested using truffle

$ truffle exec --network ganache test.js 
Using network 'ganache'.

owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=0
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=1
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=2
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=3
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=4
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=5
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=6
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=7
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=8
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=9
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=10
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=11
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=12
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=13
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=14
owner=0x627306090abab3a6e1400e9345bc60c78a8bef57, price=15
  • They say "just be aware that any web clients running web3.js will have issues". I'm using web3.js. – dougdimmadome Feb 17 '18 at 18:05
  • There are other libraries that supposedly support it. Checkout out Ethers.. github.com/ethers-io/ethers.js . Is web3.js a must? If it is, or you want to write a contract that would work with as many clients as possible, then returning structs from a public/external method is something you'll have to do without. – Howard Feb 17 '18 at 19:31
  • My question is "how can I return the fields of the struct as separate return variables, and then access them using web3.js?". – dougdimmadome Feb 17 '18 at 22:07
  • function getData(uint8 _index) external view returns (uint8,string) { return (data[_index].id, data[_index].name); } webjs would receive this as an array. – Howard Feb 17 '18 at 22:31
  • how can I change my getAdopters() function such that web3js receives it as an array? if you can just help me with that, I'd be glad to accept your answer – dougdimmadome Feb 17 '18 at 23:13

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