0

I have two contracts. The first contract has a function called get() that returns this values:

uint _value1
address _value2
address _value3
string memory _value4
string memory _value5
uint _value6
string memory _value7
address _value8

What I want is to call the function get() (Smartcontract 1) from the second contract. This is the function of the second SmartContract.

function getValues() public view
        returns(uint _value1,
                address _value2,
                address _value3,
                string memory _value4,
                string memory _value5,
                uint _value6,
                string memory _value7,
                address _value8,
                address _value9
                )
    {
        return (contract1.get(), address(contract1)); 
    }

The problem is that I get an error that says: "TypeError: Different number of arguments in return statement than in returns declaration."

I have also tried this:

{
        (_value1,_value2,_value3,_value4,_value5,_value6,_value7,_value8) = contract1.get();
        return (_value1,_value2,_value3,_value4,_value5,_value6,_value7,_value8, address(contract1)); 
}

But in this case i get the classic error: "CompilerError: Stack too deep, try removing local variables."

Is there any way to solve this problem?? I know i could call different functions to make it working.

{
       return (contract1.getValue1(),
               contract1.getValue2(),
               contract1.getValue3(),
               contract1.getValue4(),
               contract1.getValue5(),
               contract1.getValue6(),
               contract1.getValue7(),
               contract1.getValue8(),
               address(contract1)); 
}

This will work but i want to call contract1 only one time. Is there any way? I am working with the compiler version 0.6.10 Thank you in advance

2
  • "i want to call contract1 only one time" - you can call it one time (with the original get function), store the returned values into 8 local variables, and then return those 8 values along with the additional value that you want to return. This will solve the problem of calling the contract function more than once. You'll still be left with the Stack-too-Deep issue, regardless of this. Jun 19, 2020 at 12:15
  • 1
    For that, I suggest that you redesign your system, and think very carefully about why you need to return all these values from a single function to begin with. For example, are they required in another contract, or just in your (off-chain) script? If you don't actually need them in other contract, then there's no really good reason to implement this function. You can get those values in your script one by one, and if you want to optimize performance, then you can make that script do it in parallel (for example, if you're doing it in Javascript, then you can do it with Promise.all). Jun 19, 2020 at 12:16

1 Answer 1

1

An alternative is returning a struct.

If the function is public or external you will have to use the experimental abi encoder.

pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;

contract Structs {
  struct Param {
    uint _value1;
    address _value2;
    address _value3;
    string _value4;
    string _value5;
    uint _value6;
    string _value7;
    address _value8;
  }

  function get() public view returns (Param memory) {
    return Param(1, address(0x2), address(0x3), "Hi", "Mom", 3141, "Spagueti", address(0x42));
  }

  function get2() public view returns (Param memory, uint, bool) {
    return (get(), 454545, false);
  }
}

A struct uses memory so it will not consume stack slots, but gas consumption might increase.

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.