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.
I think it's the same problem as here.
When performing many operations in a short period of time, it's still neccessary to give testRPC a break here and there. Of course it can also be the case, that your testing code leads to racing conditions, which might not neccessarily be obvious or syntactical errors. It's hard to tell without the code, of course, but as long it runs on a testnet, you shouldn't have to worry that much. Of course, again, it depends also on the way your contracts are designed, for example, as one cannot guarantee that this specific scenario won't ever pop up under real conditions on the mainnet without knowing the details.
EDIT:
As of Solidity 0.4.9, bad opcode
is used for internal throws, like array out of bounds. So in your case, i'm pretty sure there is some condition in your testcode that makes the testes sometimes "try to do things", which are not intended to yet. Might be something is not properly promise-chained but sometimes being there just in time anyway.
Good Luck !
Best Answer
Sorry, I've tried your contract and it work as expected here
Contract deployed using remix.ethereum.org connected to testrpc.
query.js contractName.sol package.json