Ich versuche, eine Funktion zu erstellen, die, wenn sie aufgerufen wird, a mapping
als zwei verschiedene Arrays zurückgibt.
Das Problem, dass ich eine mapping (address => uint) content2view
und 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?
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
f
incontract 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:
Der Vertrag wird im Kovan-Netzwerk bereitgestellt und gibt die 2 Arrays zurück. Hier haben Sie die Vertragsadresse: 0x42ebaf829d341cb38bd4576a8424ce03d8c6f47c
Ich hoffe es hilft!