0

I deployed the same contract to Rinkeby, Ropsten and Tobalaba networks. Rinkeby and Ropsten work fine, but the contract execution on Tobalaba fails because of an out-of-gas exception: https://tobalaba.etherscan.com/address/0x423e873518B5C1B44654137DF55e043A99C2040a

This is the contract code:

contract ConsumptionOracle{

    // store the charge point energy consumption and charging duration in struct
    struct data {
        uint chargePointDuration;
        uint chargePointEnergy;
    }

    // associate the values with the session ID
    mapping(string => data) private values;

    // set the duration and charge point energy to the according session ID
    function setValue(uint _chargePointDuration, uint _chargePointEnergy, string memory sessionId) public{
            values[sessionId] = data(_chargePointDuration,_chargePointEnergy);
    }

    // set the duration and charge point energy using the session ID
    function getValue(string memory sessionId) public view returns(uint, uint){
        return (values[sessionId].chargePointDuration, values[sessionId].chargePointEnergy);
    }
}

I doublecheckt die ABI 100 times, so it should not be a mismatch here.

The contract on Rinkeby is as follows: https://rinkeby.etherscan.io/address/0x588d457B7b569eE6a3b9A8b5867419eD49c0454B#code

This is the full code I use to call the contract:

const Tx = require('ethereumjs-tx');
const Web3 = require('web3');
const config = require('config');

const gasLimitOracle = 1000000;
const gasPriceOracle = '1';

const web3 = new Web3(config.get('blockchain.provider.tobalaba'));
const privateKey = Buffer.from(config.get('blockchain.tobalaba.privateKey'), 'hex');
const account = config.get('blockchain.tobalaba.account');
const contractABI = [{"constant":false,"inputs":[{"name":"_chargePointDuration","type":"uint256"},{"name":"_chargePointEnergy","type":"uint256"},{"name":"sessionId","type":"string"}],"name":"setValue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"sessionId","type":"string"}],"name":"getValue","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]; 
const contractAddress = config.get('blockchain.tobalaba.oracleAddress');
const contract = new web3.eth.Contract(contractABI, contractAddress);

var exports = module.exports = {};

exports.sendToOracle = async function ConsumptionOracle(chargePointDuration, chargePointEnergy, SessionId) {

    try {
        const txcount = await web3.eth.getTransactionCount(account);
        const txObject = {
            nonce: web3.utils.toHex(txcount),
            gasLimit: web3.utils.toHex(gasLimitOracle),
            gasPrice: web3.utils.toHex(web3.utils.toWei(gasPriceOracle, 'gwei')),
            to: contractAddress,
            data: contract.methods.setValue(chargePointDuration, chargePointEnergy, SessionId).encodeABI()
        }
        const tx = new Tx(txObject)
        //sign transaction with private key from sender
        tx.sign(privateKey)

        const serializedTx = tx.serialize()
        const raw = '0x' + serializedTx.toString('hex')

        const txHash = await web3.utils.sha3(serializedTx,function(error,result){if(!error){return result}else{console.log(error)}});
        //send tx
        web3.eth.sendSignedTransaction(raw,function(error,result){if(!error){return result}else{console.log(error)}});
        // get tx result
        var result = await web3.eth.getTransaction(txHash,function(error,result){if(!error){return result}else{console.log(error)}});
        console.log(result);
        while(result == null){
            result = await web3.eth.getTransaction(txHash,function(error,result){if(!error){return result}else{console.log(error)}});
        };
        while(result.blockNumber == null){
            // wait until mined into block
            result = await web3.eth.getTransaction(txHash,function(error,result){if(!error){return result}else{console.log(error)}});
        };

        return txHash;
    } catch (err) {
        console.error(err);
        return err;
    }
}
0

It is a very simple code

// store the charge point energy consumption and charging duration in struct
struct data {
    uint chargePointDuration;
    uint chargePointEnergy;
}

// associate the values with the session ID
mapping(string => data) private values;

// set the duration and charge point energy to the according session ID
function setValue(uint _chargePointDuration, uint _chargePointEnergy, string memory sessionId) public{
        values[sessionId] = data(_chargePointDuration,_chargePointEnergy);
}

In rinkeby gas limit of 500k is enough, and gas used is less than 70k.

It is unlikely it will cause out of gas unless the client opcodes were modified.

The error trace says

Error: Bad instruction

I see the contract was compiled with a recent version of solc 0.5.7

One possible issue is the network tobalaba do not have enabled the constantinople opcodes and it causes the invalid opcode. In particular solc uses bit shift after contantinople.

  • Thank you so much! It works with changing the solc version so 0.4.23. - this was the last one without any constantinople related changes. – Felix Apr 22 at 10:18
  • If you use the command line version of solc it has a switch that allows to set the desired EVM target, ie byzantinum, constantinople, etc.So you can run a modern version of solc. – Ismael Apr 22 at 15:58
0

I had to google what on earth is Tobalaba. Seems to be some consortium Ethereum (testnet) blockchain.

As can be most easily seen from your linked Tobalaba transaction, you are reaching your gas limit (1 000 000). The network seems to support at least 80 million gas in a block, although unsure if there are transactional limits (probably not).

So you simply need to give a higher gas limit for your transaction. In your code you give it with gasLimitOracle.

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.