5

First of all, sorry for the code in Portuguese, this was a choice of the team and I had no saying on that.

I'm writing a Billet Manager, the code is as follows:

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

I'm testing it with TestRPC and 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);
             }
         );
     });
 });

I'm getting the following error:

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

Edit

This seems to be an issue with TestRPC.

I've opened an issue on github.

3

Summary

There is no error when the code is inserted into geth and run.

Can you try inserting your code into geth and see if you still the geth "invalid opcode" error.

From the OPs response in the comment, the "invalid opcode" issue is caused by the timing of the test case.



Details

Modified Your Code

I've modified your code slightly, changing the // comment into /* ... */ and added a public to your mapping structure:

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


Running geth

I'm running the Dev blockchain using the following parameters:

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


Flattened Your Code And Assigned To A Variable

You can use a service like Line Break Removal Tool to strip out your line breaks, or see How to load Solidity source file into geth for some alternatives.

I flattened your code, assigned it to a variable and pasted it into 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; }}'


Compiled Your Code

I compiled your code using the following command:

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


Inserted Your Code Into The Blockchain

I used the following commands to insert your code into the blockchain:

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

And waited for the following message:

Contract mined! Address: 0x9e550b10e770b050d6ec9af80c5fdb6540089803


Sent Transaction To Add Data

I copied the main part of your sendTransaction to insert your sample data into the blockchain:

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

And waited for the transaction to be mined.


Inspecting Data After Data Inserted

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


No Invalid Opcode

I double checked my geth messages and I did not get the "invalid opcode" message.

  • thank you for your answer. I just figured out that it's a problem with TestRPC, because if I run the tests directly on ethereum, it works perfectly. The problem is that this takes time and I need it to be fast in order to create a comprehensive test suite. – Henrique Barcelos May 5 '16 at 14:37
  • I confirm that running on an actual node gives me no error. However, the it seems like the data is not being stored, since I try to obtain it after inserting and get a zero-value struct. – Henrique Barcelos May 5 '16 at 15:19
  • see the end of my answer. data is stored. just have to use the key to the mapping. – Bokky WeAreAllAssange PooBah May 5 '16 at 15:35
  • I'm doing that, but is returning me an empty struct – Henrique Barcelos May 5 '16 at 16:18
  • Note that I have made the mapping public. Try copying and pasting the code from my answer as I did get it to work. – Bokky WeAreAllAssange PooBah May 5 '16 at 16:31

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.