Das Zurückgeben eines dynamischen Arrays funktioniert nicht

Ich versuche, eine Funktion zu erstellen, die, wenn sie aufgerufen wird, a mappingals zwei verschiedene Arrays zurückgibt.

Das Problem, dass ich eine mapping (address => uint) content2viewund ich muss diesen Wert außerhalb der Solidität bekommen. Also habe ich eine Funktion geschrieben

 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);
}

Das Problem ist, dass, wenn ich es mit remix aufrufe, kein Wert zurückgegeben wird und die Transaktion abgebrochen wird:

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

Natürlich sehe ich keinen Fehler und ich verstehe nicht, welcher ungültige Opcode ungültig ist ... Irgendwelche Hilfe?

Antworten (2)

Die Dokumentation spricht darüber:

Aufgrund von Einschränkungen der EVM ist es nicht möglich, dynamische Inhalte von externen Funktionsaufrufen zurückzugeben. Die Funktion fin contract C { function f() returns (uint[]) { ... } }gibt etwas zurück, wenn sie von web3.js aufgerufen wird, aber nicht, wenn sie von Solidity aufgerufen wird.

Die einzige Problemumgehung besteht derzeit darin, große Arrays mit statischer Größe zu verwenden.

Wie Sie sagen, müssen Sie dies als äußere Solidität bezeichnen, die Dokumentation besagt, dass Sie das Array in web3 abrufen können. Wenn Sie dies aus einer js-Anwendung oder einem anderen Programm abrufen, kann das Lesen der Variablen lokal erfolgen (null Gaskosten) und Sie können einen Getter für jeden Wert im dynamischen Array implementieren.

ich hoffe das hilft

Sie haben den Vertrag nicht erklärt. Jeder Soliditätscode (oder fast jeder) muss innerhalb von Verträgen deklariert werden, um die Funktionen aufzurufen. Weil es der Vertrag ist, der an die Blockchain gebunden ist, und er enthält Ihren gesamten Code.

So muss Ihr Code aussehen:

    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);
}
}

Hier haben Sie den Screenshot, wie die Werte zurückgegeben werden:

Geben Sie hier die Bildbeschreibung ein

Der Vertrag wird im Kovan-Netzwerk bereitgestellt und gibt die 2 Arrays zurück. Hier haben Sie die Vertragsadresse: 0x42ebaf829d341cb38bd4576a8424ce03d8c6f47c

Ich hoffe es hilft!