Fehler „ungültiger Opcode“ erhalten

Zunächst einmal entschuldigen Sie den Code auf Portugiesisch, dies war eine Entscheidung des Teams und ich hatte dazu nichts zu sagen.

Ich schreibe einen Billet Manager, der Code lautet wie folgt:

contract GerenciadorBoletos {

     struct Boleto {
         uint codigoBarra;
         uint codigoBarraDigitavel;
         uint cpfOuCnpjBeneficiario;
         uint cpfOuCnpjPagador;
         uint valorOriginal;
         uint dataVencimento;
     }

     mapping(uint => Boleto) registroBoletos;

     function inserirBoleto(
         uint codigoBarra,
         uint codigoBarraDigitavel,
         uint cpfOuCnpjBeneficiario,
         uint cpfOuCnpjPagador,
         uint valorOriginal,
         uint dataVencimento
     ) {
         Boleto memory b = Boleto(
             codigoBarra,
             codigoBarraDigitavel,
             cpfOuCnpjBeneficiario,
             cpfOuCnpjPagador,
             valorOriginal,
             dataVencimento
         );

         // I need to do some validations before store it, but there is no code yet

         registroBoletos[b.codigoBarra] = b;
     }
}

Ich teste es mit TestRPC und Mocha:

 describe('1. Inserção', function(){
     it('Deve ter inserido um boleto com os dados válidos com sucesso', function(done){
         var boletoParaInserir = gerarBoletoValido();
         console.log(boletoParaInserir);

         gerenciadorBoleto.inserirBoleto.sendTransaction(
             9872387128, 987128382, 91289312, 81273818, 50, Date.now() + 3*24*3600,
             {
                 from: web3.eth.accounts[0],
                 gas: 3000000,
             },
             function(e, result) {
                 expect(e).to.not.exist;

                 expect(result).to.exist;
                 result.should.be.above(0);
             }
         );
     });
 });

Ich erhalte den folgenden Fehler:

Uncaught AssertionError: expected [Error: Error: VM Exception while 
    executing transaction: invalid opcode

Bearbeiten

Dies scheint ein Problem mit TestRPC zu sein.

Ich habe auf github ein Issue eröffnet.

Antworten (1)

Zusammenfassung

Es gibt keinen Fehler, wenn der Code eingefügt gethund ausgeführt wird.

Können Sie versuchen, Ihren Code in getheinzufügen und zu sehen, ob Sie immer noch den Fehler "invalid opcode" von geth erhalten.

Aus der Antwort des OP im Kommentar geht hervor, dass das Problem „ungültiger Opcode“ durch das Timing des Testfalls verursacht wird.



Einzelheiten

Ihren Code geändert

Ich habe Ihren Code leicht modifiziert, indem ich den //Kommentar in /* ... */Ihre Zuordnungsstruktur geändert und eine Öffentlichkeit hinzugefügt habe:

contract GerenciadorBoletos {

    struct Boleto {
        uint codigoBarra;
        uint codigoBarraDigitavel;
        uint cpfOuCnpjBeneficiario;
        uint cpfOuCnpjPagador;
        uint valorOriginal;
        uint dataVencimento;
    }

    mapping(uint => Boleto) public registroBoletos;

    function inserirBoleto(
        uint codigoBarra,
        uint codigoBarraDigitavel,
        uint cpfOuCnpjBeneficiario,
        uint cpfOuCnpjPagador,
        uint valorOriginal,
        uint dataVencimento
    ) {
        Boleto memory b = Boleto(
            codigoBarra,
            codigoBarraDigitavel,
            cpfOuCnpjBeneficiario,
            cpfOuCnpjPagador,
            valorOriginal,
            dataVencimento
        );

        /* I need to do some validations before store it, but there is no code yet */

        registroBoletos[b.codigoBarra] = b;
    }
}


Betriebgeth

Ich führe die Dev-Blockchain mit den folgenden Parametern aus:

geth --datadir /home/user/DevData --dev --nodiscover \
  --mine --minerthreads 1 --port 30301 --maxpeers 0  \
  --verbosity 3 --rpc console


Ihren Code abgeflacht und einer Variablen zugewiesen

Sie können einen Dienst wie das Tool zum Entfernen von Zeilenumbrüchen verwenden, um Ihre Zeilenumbrüche zu entfernen, oder siehe So laden Sie die Solidity-Quelldatei in Geth für einige Alternativen.

Ich habe Ihren Code abgeflacht, ihn einer Variablen zugewiesen und ihn eingefügt in geth:

> var gerenciadorBoletosSource='contract GerenciadorBoletos { struct Boleto { uint codigoBarra; uint codigoBarraDigitavel; uint cpfOuCnpjBeneficiario; uint cpfOuCnpjPagador; uint valorOriginal; uint dataVencimento; } mapping(uint => Boleto) public registroBoletos; function inserirBoleto( uint codigoBarra, uint codigoBarraDigitavel, uint cpfOuCnpjBeneficiario, uint cpfOuCnpjPagador, uint valorOriginal, uint dataVencimento ) { Boleto memory b = Boleto( codigoBarra, codigoBarraDigitavel, cpfOuCnpjBeneficiario, cpfOuCnpjPagador, valorOriginal, dataVencimento ); /* I need to do some validations before store it, but there is no code yet */ registroBoletos[b.codigoBarra] = b; }}'


Kompiliert Ihren Code

Ich habe deinen Code mit folgendem Befehl kompiliert:

> var gerenciadorBoletosCompiled = web3.eth.compile.solidity(gerenciadorBoletosSource);


Ihren Code in die Blockchain eingefügt

Ich habe die folgenden Befehle verwendet, um Ihren Code in die Blockchain einzufügen:

var gerenciadorBoletosContract = web3.eth.contract(gerenciadorBoletosCompiled.GerenciadorBoletos.info.abiDefinition);
var gerenciadorBoletos = gerenciadorBoletosContract.new({from:web3.eth.accounts[0], data: gerenciadorBoletosCompiled.GerenciadorBoletos.code, gas: 1000000}, 
  function(e, contract) {
    if (!e) {
      if(!contract.address) {
        console.log("Contract transaction send: TransactionHash: " + 
          contract.transactionHash + " waiting to be mined...");
      } else {
        console.log("Contract mined! Address: " + contract.address);
        console.log(contract);
      }
    }
  }
)

Und auf folgende Meldung gewartet:

Contract mined! Address: 0x9e550b10e770b050d6ec9af80c5fdb6540089803


Gesendete Transaktion zum Hinzufügen von Daten

Ich habe den Hauptteil von Ihnen kopiert sendTransaction, um Ihre Beispieldaten in die Blockchain einzufügen:

> gerenciadorBoletos.inserirBoleto.sendTransaction(
    9872387128, 987128382, 91289312, 81273818, 50, Date.now() + 3*24*3600,
    {
      from: web3.eth.accounts[0],
      gas: 3000000,
    },
    function(e, result) {
      expect(e).to.not.exist;
      expect(result).to.exist;
      result.should.be.above(0);
    }
  );

Und wartete darauf, dass die Transaktion abgebaut wurde.


Überprüfen von Daten nach dem Einfügen von Daten

> gerenciadorBoletos.registroBoletos(9872387128)
[9872387128, 987128382, 91289312, 81273818, 50, 1462459836202]


Kein ungültiger Opcode

Ich habe meine gethNachrichten doppelt überprüft und die Nachricht "ungültiger Opcode" nicht erhalten.

Vielen Dank für Ihre Antwort. Ich habe gerade herausgefunden, dass es ein Problem mit TestRPC ist, denn wenn ich die Tests direkt auf Ethereum ausführe, funktioniert es perfekt. Das Problem ist, dass dies Zeit braucht, und ich brauche es schnell, um eine umfassende Testsuite zu erstellen.
Ich bestätige, dass das Ausführen auf einem tatsächlichen Knoten keinen Fehler verursacht. Es scheint jedoch, dass die Daten nicht gespeichert werden, da ich versuche, sie nach dem Einfügen zu erhalten und eine Struktur mit Nullwert zu erhalten.
siehe Ende meiner Antwort. Daten gespeichert werden. Sie müssen nur den Schlüssel für die Zuordnung verwenden.
Ich mache das, gibt mir aber eine leere Struktur zurück
Beachten Sie, dass ich die Zuordnung öffentlich gemacht habe. Versuchen Sie, den Code aus meiner Antwort zu kopieren und einzufügen, da ich ihn zum Laufen gebracht habe.
Ich habe das getan! Aber das ist ein anderes Thema. Ich eröffne eine neue Frage.