0

I'm trying to build a function that, when called, returns a mapping as two different array.

The problem that I have a mapping (address => uint) content2view and I have to get this value outside solidity. So, I wrote a function

 mapping (address => uint) content2view;
 address[] contents;
 /* [...] */
 function getStatistics() external view returns (address[], uint[]){
    address[] memory resAddr;
    uint[] memory views;
    for(uint i = 0; i<contents.length; i++){
        resAddr[i] = contents[i];
        views[i] = content2view[contents[i]];
    }
    return (resAddr, views);
}

The problem is that, when I call it with remix, no value is returned and the transaction is aborted:

  VM error: invalid opcode.
  invalid opcode    
The execution might have thrown.
Debug the transaction to get more information. 

Of course, I don't see any error and I don't understand which invalid opcode is invalid... Any help?

2

The documentation talk abou this:

Due to limitations of the EVM, it is not possible to return dynamic content from external function calls. The function f in contract C { function f() returns (uint[]) { ... } } will return something if called from web3.js, but not if called from Solidity.

The only workaround for now is to use large statically-sized arrays.

As you say you have to call this outside solidity, the documentation state that you can get the array in web3. further more, if you are colling this from a js application or any other program, reading the variable can be done locally (zero gas cost) and so you can implement a getter for each value in the dynamic array.

I hope this helps

2

You haven't declared the Contract. Every solidity code (or almost every) has to be declared inside contracts to call the functions. Because it's the contract what is committed to the blockchain, and it contains all of your code.

That's how your code must look like:

    pragma solidity^0.4.2;

contract Test {
mapping (address => uint) content2view;
 address[] contents;
 /* [...] */

 function getStatistics() external view returns (address[], uint[]){
    address[] memory resAddr;
    uint[] memory views;
    for(uint i = 0; i<contents.length; i++){
        resAddr[i] = contents[i];
        views[i] = content2view[contents[i]];
    }
    return (resAddr, views);
}
}

Here you have the screenshot as the values are returned:

enter image description here

The contract is deployed on the Kovan Network and returns the 2 arrays. Here you have the Contract address: 0x42ebaf829d341cb38bd4576a8424ce03d8c6f47c

Hope it helps!

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.