0

Look at this basic Solidity contract:

// SPDX-License-Identifier: MIT

pragma solidity 0.6.11;

contract MyContract {
   string[] public tmp;
   ...

   function read_tmp() public view returns(string[] memory){
      return tmp;
   }
}

I have create a scaffolded truffle react project.

First, i get an error when trying to deploy this contract with this command:

truffle migrate --network ropsten --reset

The error is:

TypeError: This type is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.

This error is due to string[] return type of read_tmp. I am not happy do to that but i have add this line at the top of my contract and the deploy works now:

pragma experimental ABIEncoderV2;

My first question is: Why should i enable experimental features ? My 0.6.11 compiler version should allow this feature natively...

My second question is i have tried this in App.js file:

await this.state.contract.methods.tmp().call();

Solidity should create automatically a getter called tmp() for tmp public field.

I do not understand why but i have this javascript error in my browser:

Uncaught (in promise) Error: Invalid number of parameters for "tmp". Got 0 expected 1!

Everything works if i call read_tmp(). So my question is why tmp() needs an argument ? (i have tried to pass an integer but it does not work)

Thanks a lot

2
  • My 0.6.11 compiler version should allow this feature natively... - no, it shouldn't (what makes you think it should?). Dec 23, 2020 at 18:15
  • I have seen some projects on github which works with the same pragma compiler version and return string arrays...
    – Bob5421
    Dec 23, 2020 at 18:17

2 Answers 2

2

You cannot retrieve whole array from solidity. You have to choose the index, that is why it is expecting 1 argument. If you want to get whole array elements in javascript, in solidity define a function to get the length of the array.

//Contract Code

function getTmpCount() public view returns(uint){
    return tmp.length;
}

then in javascript code:

// you get the lenght of the array
const tmpCount = await contract.methods.getTmpCount().call()

const tmps = await Promise.all(
    Array(tmpCount)
      .fill()  
      .map((element, index) => {
        return campaign.methods.tmp(index).call();
      })
  );
1

For type[] public arr, the compiler auto-generates the following function:

function arr(uint256 index) public view returns (type) {
    return arr[index];
}

It is not added to the source code of course, because that would yield a naming collision.

But it is added to the byte-code itself, essentially becoming a part of the contract.

If you want a function which returns the entire array, then you need to implement it yourself:

function getArr() public view returns (type[] memory) {
    return arr;
}

With regards to:

My 0.6.11 compiler version should allow this feature natively...

That's wrong; this feature is support under ABI encoder V2, which is activated by default only starting from solc 0.8.0 (as stated in the Solidity 0.8.0 Release Announcement).

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.