Warum kann ich in Solidity nicht mehrere Variablen mit dynamischer Größe verwenden?

Das folgende Code-Snippet funktioniert nicht.

pragma solidity ^0.4.11;

contract Test1 {
    uint[] public a;
    uint[] public b;

    function putX(uint x) public {
        a.push(x);
        b.push(block.number);
    }

    function getA() public view returns (uint[]) {
        return a;
    }

    function getB() public view returns (uint[]) {
        return b;
    }
}

Ausgang:

> test1.putX.sendTransaction(11, {from: eth.accounts[0]})
> test1.getA()
[]
> test1.getB()
[]

Das folgende Code-Snippet hingegen funktioniert.

pragma solidity ^0.4.11;

contract Test2 {
    uint[2][] public a;

    function putX(uint x) public {
        a.push([x, block.number]);
    }

    function getA() public view returns (uint[2][]) {
        return a;
    }
}

Ausgang:

> test2.putX.sendTransaction(12, {from: eth.accounts[0]})
> test2.getA()
[[12, 1151]]

Ich frage mich, warum ... Ich verwende das neueste stabile Geth (1.7)

Ich habe auch versucht, ein Array mit dynamischer Größe + eine Zuordnung zu verwenden, und es funktioniert auch nicht.

Ich bezweifle sogar, ob der Code im offiziellen Dokument funktionieren kann, da er mehrere Variablen mit dynamischer Größe verwendet:

https://solidity.readthedocs.io/en/develop/solidity-by-example.html

Weiß jemand warum das passiert ist?

Es funktioniert, Sie können ein Array mit dynamischer Größe zurückgeben. Ich habe Ihr Beispiel gegen remix.ethereum.org ausprobiert und es funktioniert wie erwartet. Sind Sie sicher, dass Ihre putXTransaktion vor dem Anruf abgebaut wurde getA? Verwenden Sie web3 v1.0 oder v0.20 oder Truffle? Einige von ihnen geben ein Versprechen zurück, und Sie müssen darauf warten, bevor Sie den Getter aufrufen.
Im Remix funktioniert es ja, habe ich auch probiert. Aber es funktioniert nicht mit der neuesten stabilen Version von geth (1.7) (ich habe ein privates Netzwerk auf einer Maschine mit einem Miner aufgebaut, die erste funktioniert nicht, die zweite funktioniert.)

Antworten (1)

Ich habe Ihren Code mit beiden Remixen, Geth v1.7.2 und v1.7.3, ausprobiert und beide funktionieren wie erwartet.

Vielleicht ist Ihr Problem, dass Sie die Abfrage machen, bevor die Transaktion abgebaut wird. Dadurch kehrt der Vertrag in den vorherigen Zustand zurück.

Wirklich? Ich habe mehr als 2 Stunden lang nachgefragt! Und es war immer noch nichts da! Das ist seltsam ... warum es in Ihrer Umgebung funktioniert ... emmm ...
Es ist eine ziemlich grundlegende Funktionalität, deshalb bin ich neugierig, warum es nicht funktioniert. Sind Sie sicher, dass die Transaktion geschürft wurde und erfolgreich ausgeführt wurde? Vielleicht geht ihm das Gas aus. Das Zurückgeben von Arrays mit dynamischer Größe sollte in Ordnung sein, Sie können keine verschachtelten dynamischen Arrays zurückgeben, dh ein Array von Strings wird fehlschlagen, aber ein Array von int oder uint sollte in Ordnung sein.
Ich sehe, was passiert ist. Du hast Recht. Nachdem ich geändert habe: "test1.putX.sendTransaction(11, {from: eth.accounts[0]})" in "test1.putX.sendTransaction(11, {from: eth.accounts[0], gas: 200000000}) ", es funktionierte! Die voreingestellte Gasmenge war nicht ausreichend! Ich wusste nicht, dass test1.putX() so viel Gas verbraucht! Aber test2.putX() funktioniert, verbraucht also nicht weniger Gas als test1.putX()... Hmm...
Gibt es eine Protokolldatei oder ähnliches, aus der ich den Status meiner eingereichten Transaktionen entnehmen kann?
Hier ist das von Truffle erzeugte Artefakt, das mit Solidity v0.4.18 (solc-js) gist.github.com/anonymous/fdc0ef75669ab57e40a84faf1bea9a03 kompiliert wurde . Sie können die Ausführung einer Transaktion von geth mit untersuchen debug.traceTransaction(txhash), von byzantinum eth.getTransactionReceipt(hash)hat ein 'Status'-Feld, das anzeigt, dass die Transaktion korrekt ausgeführt oder rückgängig gemacht wurde.